C# Unity2:使用生命周期管理器时解决泛型问题
我将 ASP MVC 3 (RC) 与 Unity 2 结合使用,取得了巨大成功。然而,我有一个无法解决的问题。在幕后,我使用 POCO(个人、公司……),我通过存储库访问它。存储库被制作为泛型(EFRepository),并使用上下文。如果通用存储库类型上没有 LifetimeManager,一切都会按预期工作:
var container = new UnityContainer();
container
.RegisterType<ObjectContext, DataLayerContext>(
new HttpRequestLifetimeManager<ObjectContext>())
.RegisterType(typeof(IRepository<>), typeof(EFRepository<>))
//Works
var unitOfWork = (IUnitOfWork)DependencyResolver.Current.GetService<IUnitOfWork>());
//Works
var webPersonRepository = (IRepository<WebPerson>)DependencyResolver.Current.GetService<IRepository<WebPerson>>();
但是,当将 LifetimeManager 添加到存储库时,解析也会失败:
var container = new UnityContainer();
container
.RegisterType<ObjectContext, DataLayerContext>(
new HttpRequestLifetimeManager<ObjectContext>())
.RegisterType(typeof(IRepository<>), typeof(EFRepository<>),
new HttpRequestLifetimeManager(typeof(IRepository<>)))
//Works
var unitOfWork = (IUnitOfWork)DependencyResolver.Current.GetService<IUnitOfWork>());
//Does NOT work anymore!
var webPersonRepository = (IRepository<WebPerson>)DependencyResolver.Current.GetService<IRepository<WebPerson>>();
有什么想法吗? HttpRequestLifetimeManager 的实现非常标准:
public class HttpRequestLifetimeManager<T> : HttpRequestLifetimeManager
{
public HttpRequestLifetimeManager() : base(typeof(T))
{
}
}
public class HttpRequestLifetimeManager : LifetimeManager, IDisposable
{
private readonly string _key;
public HttpRequestLifetimeManager(Type T)
{
_key = @"HttpRequestContextLifetimeManager" + T.Name;
}
public override object GetValue()
{
return HttpContext.Current.Items[_key];
}
public override void RemoveValue()
{
HttpContext.Current.Items.Remove(_key);
}
public override void SetValue(object newValue)
{
HttpContext.Current.Items[_key] = newValue;
}
public void Dispose()
{
RemoveValue();
}
}
任何帮助将不胜感激!
谢谢! /胜利者
I am using ASP MVC 3 (RC) with Unity 2 with great success. However, I have one problem that I cannot wrap my head around. Behind the scenes I use POCO (Person, Company, ...) which I access through repositories. The repositories are made as generics (EFRepository), and use a context. Without LifetimeManager on the generic repository type everything works as expected:
var container = new UnityContainer();
container
.RegisterType<ObjectContext, DataLayerContext>(
new HttpRequestLifetimeManager<ObjectContext>())
.RegisterType(typeof(IRepository<>), typeof(EFRepository<>))
//Works
var unitOfWork = (IUnitOfWork)DependencyResolver.Current.GetService<IUnitOfWork>());
//Works
var webPersonRepository = (IRepository<WebPerson>)DependencyResolver.Current.GetService<IRepository<WebPerson>>();
However, when adding the LifetimeManager to the repository as well, the resolving fails:
var container = new UnityContainer();
container
.RegisterType<ObjectContext, DataLayerContext>(
new HttpRequestLifetimeManager<ObjectContext>())
.RegisterType(typeof(IRepository<>), typeof(EFRepository<>),
new HttpRequestLifetimeManager(typeof(IRepository<>)))
//Works
var unitOfWork = (IUnitOfWork)DependencyResolver.Current.GetService<IUnitOfWork>());
//Does NOT work anymore!
var webPersonRepository = (IRepository<WebPerson>)DependencyResolver.Current.GetService<IRepository<WebPerson>>();
Any ideas? The implementation of the HttpRequestLifetimeManager is very standard:
public class HttpRequestLifetimeManager<T> : HttpRequestLifetimeManager
{
public HttpRequestLifetimeManager() : base(typeof(T))
{
}
}
public class HttpRequestLifetimeManager : LifetimeManager, IDisposable
{
private readonly string _key;
public HttpRequestLifetimeManager(Type T)
{
_key = @"HttpRequestContextLifetimeManager" + T.Name;
}
public override object GetValue()
{
return HttpContext.Current.Items[_key];
}
public override void RemoveValue()
{
HttpContext.Current.Items.Remove(_key);
}
public override void SetValue(object newValue)
{
HttpContext.Current.Items[_key] = newValue;
}
public void Dispose()
{
RemoveValue();
}
}
Any help would be greatly appreciated!
Thanks!
/Victor
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果有人想知道,原因是我使用的自定义 LifetimeManager 使用类型作为输入(使用泛型或作为构造函数参数)。当在泛型类型上使用 LifetimeManager 时会失败,所以不要这样做:)
最后我们决定使用 {string}+Guid.NewGuid() 作为键。
/胜利者
If anyone wants to know, the reason was that the custom LifetimeManager I used used a type as input (either using generics or as a constructor argument). When using the LifetimeManager on a generic type that will fail, so dont do that :)
In the end we decided to use {string}+Guid.NewGuid() as the key.
/Victor