Is it possible to declare a variable of type <T> without specifying T at compile time?
How to load dynamic class "MyContent"? I have 1 interface<T>, 1 abstract general class<T>and 1 class. Check the code:
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 }
}
I am trying, but it is obvious that it does not work:
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
If I change IMyContentInterface<obj>to IMyContentInterface<MyObject>, it works:
IMyContentInterface<MyObject> content = (IMyContentInterface<MyObject>)Assembly.Load("MyAssembly").CreateInstance("MyContent");
content.MyMethod();
//assembly and type names are correct
The problem is that I will not be what will be my object in the 2nd line in the definition IMyContentInterface<T>. Please, does anyone know how to do this in the .NET Framework 4.0?
"MyContent"?
- , , # , . :
List<string> list = new List<string>();
list.Add(new TcpSocket()); // This line won't compile
# , , , :
Type type = GetTypeFromReflectedAssembly();
List<type> list = new List<type>();
// This *might* work - who knows?
list.Add(new TcpSocket());
MyContent.MyMethod(), generic type <T>, , - :
IMyContentInterface content = (IMyContentInterface)Assembly.Load("MyAssembly").CreateInstance("MyContent");
content.MyMethod();
, , .:) :
, , . , . , .
MyCompany.MyProduct.MyComponent:
:
namespace MyCompany.MyProduct.MyComponent
{
public interface IMyObjectInterface
{
void MyObjectMethod();
}
/* It 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
{
}
}
MyCompany.MyProduct.MyComponent.Implementation:
, .
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() { }
}
}
MyCompany.MyProduct
, , 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);
}
}
}
:
Managed Extensibility Framework , . - , , :
- .
- .
- ( , ).
-, , :
- ( ).
- ( ).
- .
. , , , .
In my case, I used an Xml file. You can use any, I do not show these methods, because it can change for your implementation.
ISomeInterface myInterface = this.GetComponent<ISomeInterface>("SomeImplementation");
public T GetComponent<T>(string componentName)
{
// A method to dymanicly load a .dll, not shown in this example
Assembly assembly = this.GetComponentAssembly(componentName);
// A method to get a string assembly type, in this case from another source
string assemblyType = this.GetAssemblyType(componentName);
T component = (T)assembly.CreateInstance(assemblyType);
return component;
}