0

简单场景

public interface IFoo
{
   int GetData();
}

public class Foo : IFoo
{
    [CacheResult]
    public int GetData() { .... }
}

public class MyController
{
    [Dependency]
    IFoo Foo {get; set;}
}

如果我手动注册接口,解析 MyController 工作正常:

container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager(),
    new InterceptionBehavior<PolicyInjectionBehavior>(),
    new Interceptor<InterfaceInterceptor>());

var controller = container.Resolve<MyController>();

如果我尝试使用自动注册:

        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,因为传递的类型必须是接口。当然,如果我把它做成一个接口,它就可以工作,但前提是它被命名为Controller。如果我将其称为 MyController 或 SqlController 或其他名称,则映射将失败,因为它无法解析接口。

我希望只做一个程序集扫描,类似于 Spring 框架所做的,但我无法弄清楚。

我错过了什么?或者这在 Unity 中是不可能的?

4

1 回答 1

2

问题是 AllClasses.FromLoadedAssemblies 也在匹配和注册您的控制器。然后当 Unity 尝试解析控制器(不是 IFoo)时,它发现控制器没有注册接口。

这是一个帮助程序,可以将您的注册减少到仅具有匹配接口的那些类。

public static class TypeFilters
{
    public static IEnumerable<Type> WithMatchingInterface(this IEnumerable<Type> types)
    {
        return types.Where(type => 
            type.GetTypeInfo().GetInterface("I" + type.Name) != null);
    }
}

然后你可以用它来修改你的注册像这样......

AllClasses.FromLoadedAssemblies().WithMatchingInterface()
于 2015-04-23T05:16:09.043 回答