18

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? i.e. UserControl1 implements ILoad interface.

U: I can cast object to interface later, but I don't know which type in the assemblies implements the interface.

4

6 回答 6

24

这是我用过几次的一些代码。它查找程序集中实现某个接口的所有类型:

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

然后,您在 ClassLibrary1 中拥有所有实现ILoad.

然后,您可以实例化所有这些:

ILoad[] instantiatedTypes = 
    iLoadTypes.Select(t => (ILoad)Activator.CreateInstance(t)).ToArray();
于 2012-05-24T07:32:57.563 回答
6

接受的答案的唯一问题是您的程序集中必须有一个实现接口的具体类。

为了避免这种情况,我创建了能够在运行时创建动态对象并使其实现所需接口的 CustomActivator。

我把它放在github上: https ://github.com/fabriciorissetto/CustomActivator

调用很简单:

CustomActivator.CreateInstance<MyInterface>();
于 2015-05-17T03:06:34.560 回答
5

您不能创建接口的实例,但如果

UserControl1 实现 ILoad 接口

您可以将结果对象用作ILoad

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

此外,你不需要通过接口来处理它,如果你写

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

的成员ILoad可以调用为uc.SomeILoadMethod();

于 2012-05-24T07:25:17.433 回答
4

您可以使用像“NInject”这样的 IoC 容器来实现您想要的。您可以将容器配置为在请求接口时返回具体类型。

于 2012-05-24T07:28:41.660 回答
3

接口是一个接口。这是一个模板。为什么要实例化一个接口?实现接口并实例化该类。你不能实例化一个接口,它真的没有意义。

于 2012-05-24T07:26:45.063 回答
2

如果项目中引用了该库,您可以使用:

    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);
    }
于 2014-07-12T04:42:28.303 回答