通过约定和拦截进行注册会导致ResolutionFailedException [英] Registration by convention and interception causes ResolutionFailedException
问题描述
简单场景
public interface IFoo
{
int GetData();
}
public class Foo : IFoo
{
[CacheResult]
public int GetData() { .... }
}
public class MyController
{
[Dependency]
IFoo Foo {get; set;}
}
如果我手动注册接口,则解析MyController可以正常工作:
If I register the interface manually, resolving MyController works fine:
container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager(),
new InterceptionBehavior<PolicyInjectionBehavior>(),
new Interceptor<InterfaceInterceptor>());
var controller = container.Resolve<MyController>();
如果我尝试使用自动注册:
If I try to use auto-registration:
container.RegisterTypes(
AllClasses.FromLoadedAssemblies(),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.ContainerControlled,
getInjectionMembers: t => new InjectionMember[]
{
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<PolicyInjectionBehavior>(),
});
var controller = container.Resolve<MyController>();
解析失败,出现ResolutionFailedException,因为传递的Type必须是接口.当然,如果我将其设为接口,则它将起作用,但前提是将其命名为Controller.如果我将其命名为MyController或SqlController或其他名称,则映射将失败,因为它无法解析该接口.
The resolve fails with a ResolutionFailedException because the Type passed must be an interface. Of course, if I make it an interface, it will work, but only if it is named Controller. If I call it, MyController or SqlController or whatever, then the mapping fails because it cannot resolve the interface.
我希望只进行程序集扫描,类似于Spring框架,但是我无法弄清楚.
I was hoping to just do an assembly scan, similar to what the Spring framework does, but I have not been able to figure it out.
我想念什么?还是在Unity中不可能?
What am I missing? Or is this not possible in Unity?
推荐答案
问题是AllClasses.FromLoadedAssemblies也在匹配并注册您的控制器.然后,当Unity尝试解析控制器(不是IFoo)时,它会发现 controller 未在接口中注册.
The problem is that AllClasses.FromLoadedAssemblies is matching and registering your controller as well. Then when Unity tries to resolve the controller (not IFoo), it finds that the controller is not registered with an interface.
这是一个帮助程序,可以将您的注册减少到只有具有匹配接口的那些类.
Here's a helper that will reduce your registrations to only those classes that have a matching interface.
public static class TypeFilters
{
public static IEnumerable<Type> WithMatchingInterface(this IEnumerable<Type> types)
{
return types.Where(type =>
type.GetTypeInfo().GetInterface("I" + type.Name) != null);
}
}
然后您可以使用它来修改您的注册,就像这样...
and then you can use this to modify your registration like so...
AllClasses.FromLoadedAssemblies().WithMatchingInterface()
这篇关于通过约定和拦截进行注册会导致ResolutionFailedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!