我如何动态地注册具有Unity名称的泛型类? [英] How can I dynamically register generic classes with a name with Unity?

查看:169
本文介绍了我如何动态地注册具有Unity名称的泛型类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有一个BaseClass的很多类(300+)的程序集,我想用一个接口注册一个泛型类。

I have an assembly with a lot of classes (300+) with a BaseClass and I want register a generic class with a interface.

如果要解析接口的一组对象,请按{名称}进行注册。
我想在 MainViewModel 中自动创建一个对象数组。

With unity you have to register by {Name} if you want to resolve an array of objects of the interface. I want an array of objects in the MainViewModel automatically.

有没有一种方法可以通过反射自动执行此操作?
有何建议?

Is there a way to automate this with reflection? Any suggestions?

示例(伪):

Example (pseudo):

public class BaseClass
{
   public void doFoo();
}

public ClassNumber001 : BaseClass
{
}
public ClassNumber002 : BaseClass
{
}

public interface ISuperman
{
}

public class Superman : ISuperman where T : BaseClass
{
}

public MainViewModel(IEnumerable<ISuperman> lotsofSuperman)
{
}

举例来说:

Working example by hand:

container.RegisterType<ISuperman, Superman <ClassNumber001>>("ClassNumber001");
container.RegisterType<ISuperman, Superman <ClassNumber002>>("ClassNumber002");
container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>();


推荐答案

是的,您需要使用反射轻松创建所有你想要的映射。由于您使用的是Unity 3,因此您可以利用按公约注册,以便在注册课程时提供帮助(更重的提升)。

Yes, you'll need to use reflection to easily create all of the mappings that you want. Since you are using Unity 3 you can take advantage of Registration by Convention to provide help (with the heavier lifting) in registering the classes.

我已将您的伪代码编译成实际的代码:

I've taken your pseudo code and translated it into real code:

public abstract class BaseClass
{
    public abstract void DoFoo();
}

public class ClassNumber001 : BaseClass
{
    public override void DoFoo()
    {
        Console.WriteLine("001 Foo");
    }
}

public class ClassNumber002 : BaseClass
{
    public override void DoFoo()
    {
        Console.WriteLine("002 Foo");
    }
}

public interface ISuperman
{
    void Do();
}

public class Superman<T> : ISuperman where T : BaseClass
{
    private T baseClass;

    public Superman(T baseClass)
    {
        this.baseClass = baseClass;
    }

    public void Do()
    {
        this.baseClass.DoFoo();
    }
}

public class MainViewModel
{
    public MainViewModel(IEnumerable<ISuperman> lotsofSuperman)
    {
        foreach(ISuperman superman in lotsofSuperman)
        {
            superman.Do();
        }
    }
}

然后按惯例注册注册所有泛型:

Then use registration by convention to register all the generics:

IUnityContainer container = new UnityContainer();

container.RegisterTypes(
    AllClasses.FromAssembliesInBasePath().Where(t => typeof(BaseClass).IsAssignableFrom(t))
        .Select(t => typeof(Superman<>).MakeGenericType(t)),
    t => new Type[] { typeof(ISuperman) },
    t => t.GetGenericArguments().First().Name,
    WithLifetime.Transient);

container.RegisterType<IEnumerable<ISuperman>, ISuperman[]>();

container.Resolve<MainViewModel>();

在上面的代码中,我们得到了所有继承自 BaseClass ,然后构造一个类型超人< / code>并将其映射到 ISuperman code> BaseClass的。 RegisterTypes调用将相当于为每个BaseClass调用RegisterType:

In the above code we get all classes that inherit from BaseClass and then construct a type Superman<> and map that to ISuperman using the name of the BaseClass. The RegisterTypes call will be equivalent to calling RegisterType for every BaseClass:

container.RegisterType<ISuperman, Superman<ClassNumber001>("ClassNumber001");
container.RegisterType<ISuperman, Superman<ClassNumber002>("ClassNumber002");

然后当> MainViewModel 被解析时,它迭代所有 ISuperman 实例并调用一个打印输出的方法:

Then when MainViewModel is resolved it iterates over all ISuperman instances and calls a method which prints out:


001 Foo >
002 Foo

001 Foo
002 Foo

显示我们注入了2 ISuperman 实例:超人< ClassNumber001> 超人< ClassNumber002>

showing that we injected 2 ISuperman instances: Superman<ClassNumber001> and Superman<ClassNumber002>.

如果您需要针对BaseClasses的特定注册(例如非默认生命期管理器),那么您也可以按照惯例使用注册来注册这些)

If you need specific registrations for the BaseClasses (e.g. non-default lifetime manager) then you can use registration by convention to register those too).

这篇关于我如何动态地注册具有Unity名称的泛型类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆