Can I use Activator.CreateInstance with an Interface?

风格不统一 提交于 2019-11-30 17:59:08

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.

You could then instantiate all of them:

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

You cannot create instance of an interface, but if

UserControl1 implements ILoad inteface

you can use resulting object as 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();

Aphelion

What you want can be achieved using a IoC container like `NInject'. 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.

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.

I put it on the github: https://github.com/fabriciorissetto/CustomActivator

The call is simple:

CustomActivator.CreateInstance<MyInterface>();

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);
    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!