簡體   English   中英

我可以將 Activator.CreateInstance 與接口一起使用嗎?

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

我有一個例子:

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

在那里我正在創建一個類的實例,但是如何創建一個實現某些接口的類的實例? UserControl1實現ILoad接口。

U:我可以稍后將對象轉換為接口,但我不知道程序集中的哪種類型實現了接口。

這是我使用過幾次的一些代碼。 它在程序集中查找實現某個接口的所有類型:

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();

接受的答案的唯一問題是您的程序集中必須有一個實現接口的具體類。

為了避免這種情況,我創建了我的 CustomActivator,它能夠在運行時創建動態對象並使其實現所需的接口。

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

調用很簡單:

CustomActivator.CreateInstance<MyInterface>();

您不能創建接口的實例,但是如果

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();

您可以使用像“NInject”這樣的 IoC 容器來實現您想要的。 您可以將容器配置為在請求接口時返回具體類型。

接口是一個接口。 這是一個模板。 為什么要實例化一個接口? 實現接口並實例化該類。 你不能實例化一個接口,它真的沒有意義。

如果在項目中引用了該庫,您可以使用:

    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