简体   繁体   English

我可以将 Activator.CreateInstance 与接口一起使用吗?

[英]Can I use Activator.CreateInstance with an Interface?

I have an example:我有一个例子:

        Assembly asm = Assembly.Load("ClassLibrary1");
        Type ob = asm.GetType("ClassLibrary1.UserControl1");
        UserControl uc = (UserControl)Activator.CreateInstance(ob);
        grd.Children.Add(uc);

There I'm creating an instance of a class, but how can I create an instance of a class which implements some interface?在那里我正在创建一个类的实例,但是如何创建一个实现某些接口的类的实例? ie UserControl1 implements ILoad interface.UserControl1实现ILoad接口。

U: I can cast object to interface later, but I don't know which type in the assemblies implements the interface. U:我可以稍后将对象转换为接口,但我不知道程序集中的哪种类型实现了接口。

This is some code i have used a few times.这是我使用过几次的一些代码。 It finds all types in an assembly that implement a certain interface:它在程序集中查找实现某个接口的所有类型:

Type[] iLoadTypes = (from t in Assembly.Load("ClassLibrary1").GetExportedTypes()
                     where !t.IsInterface && !t.IsAbstract
                     where typeof(ILoad).IsAssignableFrom(t)
                     select t).ToArray();

Then you have all types in ClassLibrary1 that implement ILoad .然后,您在 ClassLibrary1 中拥有实现ILoad所有类型。

You could then instantiate all of them:然后你可以实例化所有这些:

ILoad[] instantiatedTypes = 
    iLoadTypes.Select(t => (ILoad)Activator.CreateInstance(t)).ToArray();

The only problem with the accepted answer is that you must have a concrete class on your assembly that implements the interface.接受的答案的唯一问题是您的程序集中必须有一个实现接口的具体类。

To avoid that I have created my CustomActivator that is able to create a dynamic object at runtime and make it implements the desired interface.为了避免这种情况,我创建了我的 CustomActivator,它能够在运行时创建动态对象并使其实现所需的接口。

I put it on the github: https://github.com/fabriciorissetto/CustomActivator我放在github上: https : //github.com/fabriciorissetto/CustomActivator

The call is simple:调用很简单:

CustomActivator.CreateInstance<MyInterface>();

You cannot create instance of an interface, but if您不能创建接口的实例,但是如果

UserControl1 implements ILoad inteface UserControl1 实现 ILoad 接口

you can use resulting object as ILoad您可以将结果对象用作ILoad

ILoad uc = (ILoad)Activator.CreateInstance(ob);
grd.Children.Add(uc);

Moreover, you do not need to treat it via interface, if you write而且,你不需要通过接口来对待它,如果你写

UserControl1 uc = (UserControl1)Activator.CreateInstance(ob);
grd.Children.Add(uc);

Members of ILoad would be callable as uc.SomeILoadMethod();的成员ILoad将是可调用作为uc.SomeILoadMethod();

What you want can be achieved using a IoC container like `NInject'.您可以使用像“NInject”这样的 IoC 容器来实现您想要的。 You can configure a container to return a concrete type when you've requested an interface.您可以将容器配置为在请求接口时返回具体类型。

Interface is an interface.接口是一个接口。 It's a template.这是一个模板。 Why would you want to instantiate an interface?为什么要实例化一个接口? Implement the interface and instantiate that class.实现接口并实例化该类。 You can't instantiate an interface, it doesn't really make sense.你不能实例化一个接口,它真的没有意义。

If the library was referenced in the project you may use:如果在项目中引用了该库,您可以使用:

    static public IEnumerable<Type> GetTypesFromLibrary<T>(String library)
    {
        var MyAsemblies = AppDomain.CurrentDomain.GetAssemblies()
                         .Where(a=>a.GetName().Name.Equals(library))
                         .Select(a=>a);
        var Exported = MyAsemblies
                         .FirstOrDefault()
                         .GetExportedTypes();
        var Asignable = Exported
                         .Where (t=> !t.IsInterface && !t.IsAbstract
                         && typeof(T).IsAssignableFrom(t))
                         .Select(t=>t)
                         .AsEnumerable();
        return Asignable;
    }

    static public T GetInstanceOf<T>(String library, String FullClassName)
    {
        Type Type = GetTypesFromLibrary<T>(library)
                        .Where(t => t.FullName.Equals(FullClassName))
                        .FirstOrDefault();
        if (Type != null)
        {
            T Instance = (T)Activator.CreateInstance(Type);
            return Instance;
        }
        return default(T);
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM