使用Unity,如何使用通用接口自动调整泛型类,而无需向其注册每种类型

时间:2010-02-11 22:15:36

标签: generics unity-container ioc-container

我正在使用Unity和Unity.AutoRegistration。 Unity的这一行:

unityContainer.RegisterType(typeof(IAction<>), typeof(Action<>));

有效地将项目中的每个类注册到IAction / Action:

unityContainer.RegisterType<IAction<ObjectA>, Action<ObjectA>>();
unityContainer.RegisterType<IAction<ObjectB>, Action<ObjectB>>();
unityContainer.RegisterType<IAction<ObjectC>, Action<ObjectC>>();
[...]
unityContainer.RegisterType<IAction<UnrelatedObject>, Action<UnrelatedObject>>();
[...]

但是,我只想要注册特定的对象。我该怎么办?我的猜测是为特定的类添加一个自定义属性装饰器。

[ActionAtribute]
public class ObjectB
{ [...] }

尝试使用Unity.AutoRegistration。这就是我被困在的地方:

unityContainer.ConfigureAutoRegistration()
    .Include(If.DecoratedWith<ActionAtribute>,
             Then.Register()
             .As   ?? // I'm guessing this is where I specify
             .With ?? // IAction<match> goes to Action<match>
             )
    .ApplyAutoRegistration();

1 个答案:

答案 0 :(得分:6)

Include方法具有重载,允许您传递lambda以注册您的类型。要使用属性实现您想要的功能,您可以这样做:

        unityContainer.ConfigureAutoRegistration()
            .Include(If.DecoratedWith<ActionAtribute>,
                     (t, c) => c.RegisterType(typeof(IAction<>).MakeGenericType(t), typeof(Action<>).MakeGenericType(t)))
            .IncludeAllLoadedAssemblies()
            .ApplyAutoRegistration();

另外,Include方法的第一个参数是Predicate,所以如果你不想使用属性而是使用其他机制来定义要包含或排除的类型,你可以这样做:

        // You may be getting these types from your config or from somewhere else
        var allowedActions = new[] {typeof(ObjectB)}; 
        unityContainer.ConfigureAutoRegistration()
            .Include(t => allowedActions.Contains(t),
                     (t, c) => c.RegisterType(typeof(IAction<>).MakeGenericType(t), typeof(Action<>).MakeGenericType(t)))
            .IncludeAllLoadedAssemblies()
            .ApplyAutoRegistration();