Mar*_*ark 4 asp.net-mvc autofac lightspeed
我正在编写一个ASP.NET MVC网站,使用autofac进行依赖项注入,并将Mindscape的Lightspeed用作ORM。有一个UserRepository类,该类取决于光速UnitOfWork,并为Logon控制器提供服务。
问题:在UserRepository使用完UnitOfWork之前,将其处置。
public class UserRepository : IUserRepository
{
private readonly BluechipModelUnitOfWork _unitOfWork;
public UserRepository(BluechipModelUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public Principal GetPrincipal(string name)
{
// This line throws an ObjectDisposedException - UnitOfWork is already disposed.
return _unitOfWork.Principals.FirstOrDefault(p => p.Name == name);
}
...
Run Code Online (Sandbox Code Playgroud)
在Global.asax中,依存关系接线如下:
public class MvcApplication : HttpApplication, IContainerProviderAccessor
{
private static void RegisterAutofac()
{
var builder = new ContainerBuilder();
// Register the lightspeed context as a singleton
builder.RegisterInstance(new LightSpeedContext<BluechipModelUnitOfWork>("LightSpeedBluechip"))
.As<LightSpeedContext<BluechipModelUnitOfWork>>()
.SingleInstance();
// Register the unit of work constructor so that a new instance is bound to each HttpRequest
builder.Register(c => c.Resolve<LightSpeedContext<BluechipModelUnitOfWork>>().CreateUnitOfWork())
.As<BluechipModelUnitOfWork>()
.InstancePerLifetimeScope();
// Register user repository to be one instance per HttpRequest lifetime
builder.Register(c => new UserRepository(c.Resolve<BluechipModelUnitOfWork>()))
.As<IUserRepository>()
.InstancePerLifetimeScope();
builder.Register(c => new CurrentUserService(
c.Resolve<HttpSessionState>(),
c.Resolve<IUserRepository>(),
c.Resolve<IMembershipService>())
).As<ICurrentUserService>()
.CacheInSession();
builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>();
builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired().InjectActionInvoker();
builder.RegisterModelBinders(Assembly.GetExecutingAssembly());
// Set the container provider up with registrations.
_containerProvider = new ContainerProvider(builder.Build());
// Set the controller factory using the container provider.
ControllerBuilder.Current.SetControllerFactory(new AutofacControllerFactory(_containerProvider));
Run Code Online (Sandbox Code Playgroud)
鉴于上述注册,为什么autofac会处理UnitOfWork(
我能够找到问题所在-这是一个愚蠢但微妙的陷阱...我注册了CurrentUserService类,如下所示:
builder.Register(c => new CurrentUserService(
c.Resolve<HttpSessionState>(),
c.Resolve<IUserRepository>(),
c.Resolve<IMembershipService>())
).As<ICurrentUserService>()
.CacheInSession();
Run Code Online (Sandbox Code Playgroud)
问题出在CacheInSession()上,因为CurrentUserService依赖于IUserRepository,它是autofac忠实地注入的,但是在第一个请求结束时进行了处理。
这揭示了一些显而易见的东西,但是在连接依赖项注入时需要注意:
确保高阶从属始终与它们所依赖的服务具有相同或较短的生存期。就我而言,解决方案是更改以上代码:
builder.Register(c => new CurrentUserService(
c.Resolve<HttpSessionState>(),
c.Resolve<IUserRepository>(),
c.Resolve<IMembershipService>())
).As<ICurrentUserService>()
.InstancePerLifetimeScope();
Run Code Online (Sandbox Code Playgroud)
....这样可以防止CurrentUserService脱离其依赖的实例。
| 归档时间: |
|
| 查看次数: |
1657 次 |
| 最近记录: |