Fab*_*sta 5 .net c# generics assemblies
如何动态加载"MyContent"类?我有1,1 interface<T>个抽象泛型class<T>和1个类.检查我的代码:
public interface IMyObjectInterface{
}
public abstract MyAbstractObject : IMyObjectInterface{
}
public class MyObject : MyAbstractObject{
}
public interface IMyContentInterface<T> where T : MyAbstractObject
{
void MyMethod();
}
public abstract MyAbstractContent<T>, IMyContentInterface<T> where T : MyAbstractObject
{
public abstract void MyMethod();
}
public public class MyContent : MyAbstractContent<MyObject>
{
public override void MyMethod() { //do something }
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试,但显然它不起作用:
IMyObjectInterface obj = (IMyObjectInterface)Assembly.Load("MyAssembly").CreateInstance("MyObject");
IMyContentInterface<obj> content = (IMyContentInterface<obj>)Assembly.Load("MyAssembly").CreateInstance("MyContent");
content.MyMethod();
//assembly and type names are correct
Run Code Online (Sandbox Code Playgroud)
如果我换IMyContentInterface<obj>到IMyContentInterface<MyObject>,工作:
IMyContentInterface<MyObject> content = (IMyContentInterface<MyObject>)Assembly.Load("MyAssembly").CreateInstance("MyContent");
content.MyMethod();
//assembly and type names are correct
Run Code Online (Sandbox Code Playgroud)
问题是,在定义时,我不会在第二行中成为我的对象IMyContentInterface<T>.请问有人知道如何在.NET Framework 4.0中执行此操作吗?
在该项目< >必须是一个类型不是对象.
我的车是汽车的一个对象所以
Car myCar=new Car();
Run Code Online (Sandbox Code Playgroud)
我想要一个列表来保存我的汽车(Car类型的对象).
List<Car> myCars = new List<Car>();
Run Code Online (Sandbox Code Playgroud)
然后我们将Car类型的对象添加到我的列表中.
myCars.Add(myCar);
myCars.Add(anotherCar);
Run Code Online (Sandbox Code Playgroud)
如何动态加载"MyContent"类?
加载它并不难 - 你已经知道如何做到这一点,但C#泛型在编译时是强类型,检查和保证.考虑以下代码:
List<string> list = new List<string>();
list.Add(new TcpSocket()); // This line won't compile
Run Code Online (Sandbox Code Playgroud)
如果你被允许声明这样的泛型,C#编译器不能告诉你这是非法的:
Type type = GetTypeFromReflectedAssembly();
List<type> list = new List<type>();
// This *might* work - who knows?
list.Add(new TcpSocket());
Run Code Online (Sandbox Code Playgroud)
如果您的最终目标是调用MyContent.MyMethod()并且与泛型类型参数没有任何关系<T>,请考虑声明一个非泛型接口,您可以在继承层次结构中的某处实现,并使用它声明您的实例变量:
IMyContentInterface content = (IMyContentInterface)Assembly.Load("MyAssembly").CreateInstance("MyContent");
content.MyMethod();
Run Code Online (Sandbox Code Playgroud)
我不得不读几遍,但我想出了你在问什么.:)这个问题是另一个问题的具体实例:
也就是说,这是一个如何将它用于测试用例的示例.显然你可以改变它.此外,请不要错过我在答案结尾处的最后一点.
在此程序集中定义接口:
namespace MyCompany.MyProduct.MyComponent
{
public interface IMyObjectInterface
{
void MyObjectMethod();
}
/* It's important to include this non-generic interface as a base for
* IMyContentInterface<T> because you will be able to reference this
* in the assembly where you load components dynamically.
*/
public interface IMyContentInterface
{
Type ObjectType
{
get;
}
void MyContentMethod();
}
public interface IMyContentInterface<T> : IMyContentInterface
where T : IMyObjectInterface
{
}
}
Run Code Online (Sandbox Code Playgroud)
实现将动态加载的此程序集中的接口.
namespace MyCompany.MyProduct.MyComponent
{
public abstract class MyAbstractObject : IMyObjectInterface
{
public abstract void MyObjectMethod();
}
public class MyObject : MyAbstractObject
{
public override void MyObjectMethod() { }
}
public abstract class MyAbstractContent<T> : IMyContentInterface<T>
where T : MyAbstractObject
{
public Type ObjectType
{
get
{
return typeof(T);
}
}
public abstract void MyContentMethod();
}
public class MyContent : MyAbstractContent<MyObject>
{
public override void MyContentMethod() { }
}
}
Run Code Online (Sandbox Code Playgroud)
您的程序由此程序集组成,这是我从Managed Extensibility Framework中提取的术语.这个程序集引用MyCompany.MyProduct.MyComponent但不是MyCompany.MyProduct.MyComponent.Implementation假设接口比产品开发期间的实现更可能保持兼容.这种设计试图有利于凝聚力而不是耦合(一对经常被误解的词),但实际的实施往往在实现这一目标的过程中有很大差异.
namespace MyCompany.MyProduct
{
using MyCompany.MyProduct.MyComponent;
using System.Reflection;
using System.Security.Policy;
public class ComponentHost
{
public void LoadComponents()
{
Assembly implementation = LoadImplementationAssembly();
/* The implementation assembly path might be loaded from an XML or
* similar configuration file
*/
Type objectType = implementation.GetType("MyCompany.MyProduct.MyComponent.MyObject");
Type contentType = implementation.GetType("MyCompany.MyProduct.MyComponent.MyContent");
/* THIS assembly only works with IMyContentInterface (not generic),
* but inside the implementation assembly, you can use the generic
* type since you can reference generic type parameter in the source.
*/
IMyContentInterface content = (IMyContentInterface)Activator.CreateInstance(contentType);
}
private Assembly LoadImplementationAssembly()
{
/* The implementation assembly path might be loaded from an XML or
* similar configuration file
*/
string assemblyPath = "MyCompany.MyProduct.MyComponent.Implementation.dll";
return Assembly.LoadFile(assemblyPath);
}
}
}
Run Code Online (Sandbox Code Playgroud)
该托管扩展框架是建成一个共同的解决方案,您正在使用的问题.经过一段时间的努力,我充满信心地说它具有以下不错的特性:
如果它符合以下一项或多项的任何组合,我会很容易地推荐它作为新应用程序工作人员的可行选项: