我在项目中使用Unity.MVC3。
我已经实现了通用工作单元 - UnitOfWork<TContext>
,我希望每个请求都能创建它。所以利用Unity.MVC3我就这样做了:
unityContainer.RegisterType(typeof(IUnitOfWork<>), typeof(UnitOfWork<>), new HierarchicalLifetimeManager());
我在基础存储库中使用了提到的UOW。某些特定存储库使用基本存储库,某些服务使用这些特定存储库。
假设我们有UserRepository和UserService。
UserRepository构造函数或多或少看起来像这样:
public UserRepository(IUnitOfWork<UserContext> unitOfWork)
: base(unitOfWork)
{
}
Inside UserService我正在使用UserRepository,我想拥有与UserRepository一样的UOW实例:
public UserService(IUserRepository userRepository, IUnitOfWork<UserContext> unitOfWork)
{
}
当我使用Unity.MVC3并使用HierarchicalLifetimeManager注册UOW时,我应该在UserRepository和UserService中获得相同的UOW实例,对吧?
问题在于,如果我第一次运行网站,则会创建两个不同的UOW实例,并且只调用这两个实例中的一个,调用Dispose方法。当页面加载并按下刷新按钮时,一切似乎都是正确的 - 只创建了一个实例。
似乎问题出现在注册的泛型类型中。
如果您想重现此问题,可以下载Unity.MVC3.Example代码,将IExampleContext设为通用并尝试运行。
您是否知道可能导致问题的原因以及如何解决此问题?提前谢谢。
答案 0 :(得分:0)
实际上我认为PerResolveLifetimeManager就是您所需要的。
在依赖链中只创建一个UOW,但每次解析链时都会创建一个新的UOW。
HierarchicalLifetimeManager是相反的行为。
答案 1 :(得分:0)
这是我的替代解决方案:
我创建了PerRequestLifetimeManager:
public class PerRequestLifetimeManager<T> : LifetimeManager, IDisposable
{
public override object GetValue()
{
return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
}
public override void RemoveValue()
{
HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
}
public override void SetValue(object newValue)
{
HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] = newValue;
}
public void Dispose()
{
}
}
Inside UserDomain我注册了IUnitOfWork类型:
RegisterType<IUnitOfWork<UsersContext>, UnitOfWork<UsersContext>>(new PerRequestLifetimeManager<IUnitOfWork<UsersContext>>());
我创建了PerRequestLifetimeHttpModule并在Web.config中注册了它:
public class PerRequestLifetimeHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.EndRequest += (sender, e) => UnityDependencyResolver.DisposePerRequestLifetimeItems();
}
public void Dispose()
{
}
}
<system.webServer>
<modules runAllManagedModulesForAllRequests="false">
<add name="PerRequestLifetimeHttpModule" type="<namespace>.PerRequestLifetimeHttpModule, <assemblyName>" />
</modules>
</system.webServer
最后一步 - 在我的自定义UnityDependencyResolver中创建了DisposePerRequestLifetimeItems静态函数,该函数在PerRequestLifetimeHttpModule中使用:
public static void DisposePerRequestLifetimeItems()
{
foreach (var item in HttpContext.Current.Items.OfType<DictionaryEntry>().Where(item => item.Value is IDisposable))
{
((IDisposable)item.Value).Dispose();
}
}