统一注册封闭类型

Registering closed types with unity

我有如下界面

public interface IViewModelFactory<out TViewModel>
{
    TViewModel Create();
}

我有几个 类 将实现此接口,如

public class LeaseCreateViewModelFactory : IViewModelFactory<LeaseCreateModel>
{

    public LeaseCreateModel Create()
    {
        return null;
    }
}

public class LeaseEditViewModelFactory : IViewModelFactory<LeaseEditModel>
    {

        public LeaseEditModel Create()
        {
            return null;
        }
    }

如何使用 Unity 注册所有实现 IViewModelFactory 的封闭类型,我已经看过,但我只能找到封闭类型的单独注册。

在 Microsoft 文档中找到如何为个人注册执行此操作 喜欢:

container.RegisterType<IValidator<StockQuote>, RandomStockQuoteValidator>();

有没有办法自动执行此操作?

找到这个link

http://www.danderson00.com/2010/09/automatically-register-implementors-of.html

我希望我可以在不借助扩展的情况下做到这一点,但它确实有效...

public static void RegisterAllTypesForOpenGeneric(this IUnityContainer container, Type openGenericType, Assembly targetAssembly)
{
      if (!openGenericType.IsGenericTypeDefinition) throw new ArgumentException("typeToRegister must be an open generic type", "typeToRegister");

         foreach (Type type in targetAssembly.GetExportedTypes())
         {
             if (openGenericType.IsInterface)
                  RegisterInterfaceTypes(container, openGenericType, type, type);
             else
                  RegisterBaseTypes(container, openGenericType, type, type);           
         }
}

private static void RegisterInterfaceTypes(IUnityContainer container, Type openGenericType, Type targetType, Type typeToRegister)
{
    foreach (Type interfaceType in targetType.GetInterfaces())
    if (interfaceType.IsGenericType && !interfaceType.ContainsGenericParameters && openGenericType.IsAssignableFrom(interfaceType.GetGenericTypeDefinition()))
         container.RegisterType(interfaceType, typeToRegister);
}

private static void RegisterBaseTypes(IUnityContainer container, Type openGenericType, Type targetType, Type typeToRegister)
{
     if (targetType.BaseType != null && targetType.BaseType != yypeof(object))
         if (targetType.BaseType.IsGenericType && openGenericType.IsAssignableFrom(targetType.BaseType.GetGenericTypeDefinition()))
              container.RegisterType(targetType.BaseType, typeToRegister);
    else
        RegisterBaseTypes(container, openGenericType, targetType.BaseType, typeToRegister);
 }

您可以通过扩展方法RegisterTypes来使用Registration by Convention

首先添加以下方法来定位您的具体类型和实现的接口:

private static IEnumerable<Type> GetImplementedIViewModelFactoryTypes(Type type)
{
    return type.GetInterfaces().Where(iface => iface.IsGenericType &&
        iface.GetGenericTypeDefinition() == typeof(IViewModelFactory<>));
}

private static bool ImplementsIViewModelFactory(Type type)
{
    return GetImplementedIViewModelFactoryTypes(type).Any();
}

private IEnumerable<Type> GetConcreteFactoryTypes()
{
    // You may want to change which assemblies are scanned here
    return AllClasses.FromAssemblies(typeof(IViewModelFactory<>).Assembly)
        .Where(ImplementsIViewModelFactory);
}

那么你可以这样使用:

container.RegisterTypes(GetConcreteFactoryTypes(), GetImplementedIViewModelFactoryTypes);

这将自动连接所有 IViewModelFactory<T> 实施。然后可以正常解决它们:

var leaseEditViewModelFactory = container.Resolve<IViewModelFactory<LeaseEditViewModel>>();