我有一个使用GenericHandler的应用程序,并希望使用 Unity 注入依赖项。无论我尝试什么,我都会收到错误:
[MissingMethodException: No parameterless constructor defined for this object.]
System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean
我试图按照http://geekswithblogs.net/Rhames/archive/2012/09/11/loosely-coupled-.net-cache-provider-using-dependency-injection.aspx上的示例进行操作。
我对处理程序的构造函数如下:
public class GetPerson : IHttpHandler
{
private IPersonRepository repo;
public GetPerson(IPersonRepository repo)
{
this.repo = repo;
}
IPersonRepository由CachedPersonRepository实现。 CachedPersonRepository包装PersonRepository(如果在缓存中找不到项目,则用于DataAccess)。 CachedPersonRepository和PersonRepository都是IPersonRepository :
public class CachedPersonRepository : IPersonRepository
{
private ICacheProvider<Person> cacheProvider;
private IPersonRepository personRepository;
public CachedPersonRepository(IPersonRepository personRepository, ICacheProvider<Person> cacheProvider)
{
此IPersonRepository personRepository是无参数的。
ICacheProvider<Person> is implemented by MemcachedCacheProvider<T>:
public class MemcachedCacheProvider<T> : ICacheProvider<T>
{
public T Get(string key, Func<T> retrieveData, DateTime? absoluteExpiry, TimeSpan relativeExpiry)
{
我尝试在Global.asax文件Application_Start中初始化Unity容器失败。 DI对我来说是新的,我非常感谢任何有关我出错的建议。
答案 0 :(得分:2)
这里实际上有两个问题。
首先,CachedPersonRepository使用我以前没有正确理解的Decorator模式。一旦我理解了这一点,我就可以使用这个配置适当地注册和解析PersonRepository:
public static void Configure(IUnityContainer container)
{
container.RegisterType<ICacheProvider<Person>, MemcachedCacheProvider<Person>>();
container.RegisterType<IPersonRepository, PersonRepository>("PersonRepository", new ContainerControlledLifetimeManager());
container.RegisterType<IPersonRepository, CachedPersonRepository>(
new InjectionConstructor(
new ResolvedParameter<IPersonRepository>("PersonRepository"),
new ResolvedParameter<ICacheProvider<Person>>()));
container.Resolve<IPersonRepository>();
}
修复此问题后,我仍然看到“为此对象定义的无参数构造函数”错误。
原因是我正在使用IHttpHandler,并且无法在构造函数中注入依赖项。
我通过使用Property注入来解决这个问题:
具有依赖关系属性的Repository属性已添加到GetPerson处理程序中:
public class GetPerson : HandlerBase
{
[Dependency]
public IPersonRepository Repository { get; set; }
需要一个新的http模块来检查实现我的HandlerBase的处理程序的请求:
public class UnityHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += OnPreRequestHandlerExecute;
}
public void Dispose() { }
private void OnPreRequestHandlerExecute(object sender, EventArgs e)
{
IHttpHandler currentHandler = HttpContext.Current.Handler as HandlerBase;
if (currentHandler != null)
{
HttpContext.Current.Application.GetContainer().BuildUp(
currentHandler.GetType(), currentHandler);
}
}
}
资源:
http://download.microsoft.com/download/4/D/B/4DBC771D-9E24-4211-ADC5-65812115E52D/DependencyInjectionWithUnity.pdf(第4章,第60-63页)
http://msdn.microsoft.com/en-us/library/ff664534(v=pandp.50).aspx