我有一个多层应用程序,我的DbContext
和UnitOfWork
的实现位于我的服务层。此图层没有System.Web
的引用。
与我的CompositionRoot
类一起实现的是我的UI层,它使用扩展来初始化我的所有注入。
但是我的DbContext
和UnitOfWork
需要一个请求范围,我无法像下面的示例那样设置它,因为我无法访问HttpContext
或{{1 }}。
我应该将此WebRequestLifestyle
扩展程序移动到我的UI层以使用请求范围,还是应该仅在我的服务层中引用System.Web或其他方法? < / p>
我是依赖注入的新手,所以也许我只是对这种情况下的最佳实践过于偏执。
ServiceLayer /的EntityFramework / CompositionRoot.cs
RegisterEntityFramework(...)
UILayer / App_Start / CompositionRoot.cs
public static class CompositionRoot
{
public static void RegisterEntityFramework(this Container container)
{
var lifestyle = Lifestyle.CreateHybrid(
lifestyleSelector: () => HttpContext.Current != null, // HttpContext not available
trueLifestyle: new WebRequestLifestyle(),
falseLifestyle: new LifetimeScopeLifestyle()
);
var contextRegistration = lifestyle.CreateRegistration<EntityDbContext, EntityDbContext>(container);
container.AddRegistration(typeof(EntityDbContext), contextRegistration);
container.AddRegistration(typeof(IUnitOfWork), contextRegistration);
}
}
答案 0 :(得分:1)
composition root是应用程序启动路径的一部分。在您的情况下,您的Web应用程序。系统中的组合根references all assemblies。将业务层特定注册移出此部分的唯一原因是业务层被多个终端应用程序(例如MVC应用程序和WCF Web服务)重用。
如果您将所有内容移至Web应用程序,则DbContext的注册将很简单:
var scopedLifestyle = new WebRequestLifestyle();
var contextRegistration =
scopedLifestyle.CreateRegistration<EntityDbContext, EntityDbContext>(container);
container.AddRegistration(typeof(EntityDbContext), contextRegistration);
container.AddRegistration(typeof(IUnitOfWork), contextRegistration);
如果您有多个应用程序并且需要重用业务层的注册逻辑,那么您并不确切知道要使用哪种生活方式。在这种情况下,您可以使用ScopedLifestyle
:
public static void RegisterEntityFramework(this Container container,
ScopedLifestyle lifestyle)
{
var contextRegistration =
lifestyle.CreateRegistration<EntityDbContext, EntityDbContext>(container);
container.AddRegistration(typeof(EntityDbContext), contextRegistration);
container.AddRegistration(typeof(IUnitOfWork), contextRegistration);
}
您可以在Application_Start中调用此方法,如下所示:
container.RegisterEntityFramework(new WebRequestLifestyle());