我有一个例子:
Assembly asm = Assembly.Load("ClassLibrary1");
Type ob = asm.GetType("ClassLibrary1.UserControl1");
UserControl uc = (UserControl)Activator.CreateInstance(ob);
grd.Children.Add(uc);
我正在创建一个类的实例,但是如何创建实现某个接口的类的实例?即 UserControl1 实现 ILoad 接口。
U:我可以稍后将对象转换为接口,但我不知道程序集中的哪个类型实现了接口。
答案 0 :(得分:19)
这是我使用过几次的代码。它在程序集中查找实现特定接口的所有类型:
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();
答案 1 :(得分:4)
您无法创建界面实例,但如果
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();
答案 2 :(得分:4)
使用像“NInject”这样的IoC容器可以实现您想要的功能。 您可以将容器配置为在请求接口时返回具体类型。
答案 3 :(得分:3)
接口是一个接口。这是一个模板。你为什么要实例化一个接口?实现接口并实例化该类。你不能实例化一个接口,它真的没有意义。
答案 4 :(得分:3)
接受的答案唯一的问题是你必须在程序集上有一个实现接口的具体类。
为了避免我创建了我的CustomActivator,它能够在运行时创建动态对象并使其实现所需的界面。
我把它放在github上: https://github.com/fabriciorissetto/CustomActivator
电话很简单:
CustomActivator.CreateInstance<MyInterface>();
答案 5 :(得分: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);
}