我在业务逻辑程序集中有以下内容:
public class BusinessEntity
{
...
}
public class Customer : BusinessEntity
{
...
}
public interface IEntityManager <T> where T : BusinessEntity
{
T SaveData(T oData);
}
public CustomerEntityManager : IEntityManager <Customer>
{
Customer SaveData(Customer o)
{
...
}
}
我被迫通过反射和实例化CustomersEntityManager
在我当前的项目中加载上面的程序集(由于一些显而易见的原因)。想象一下,我正在编写如下方法:
public class EntityFactory
{
public static IEntityManager<BusinessEntity> GetManagerInstance(string EntityName)
{
var asm = GetAssembly(); // imagine that I loaded the assembly somehow
EntityName = "Customer"; // just imagine
object o;
// DO NOT KNOW WHAT TO WRITE HERE.
return o as IEntityManager<BusinessEntity>; // this needs to be an instance of CustomerEntityManager.
}
}
我可以选择修改业务程序集。但实例创建需要在我当前的项目中,我必须使用反射加载业务程序集。所有数据类型仅在运行时才知道。
我可能会遗漏一些基本的东西,或者可能是错误的编码。请帮我解决这个问题。
更新:
遵循“driss”建议,如下:
string fullTypeName = "Your.Namespace." + EntityName + "EntityManager";
object o = Activator.CreateInstance(asm.FullName, fullTypeName);
看起来它创建了实例。但是,最终出现了错误:
无法将'o'(实际类型为'CustomerEntityManager')转换为'IEntityManager'
执行以下语句时:
return o as IEntityManager<BusinessEntity>
由于
答案 0 :(得分:3)
您需要以某种方式构造完整的类型名称,以便您可以获得表示该类型的Type
实例。您可能认为类型名称依赖于约定,因此您可以找到完整的类型名称:
string fullTypeName = "Your.Namespace." + EntityName + "EntityManager";
object o = Activator.CreateInstance(asm.FullName, fullTypeName);
然后,只需调用Activator.CreateInstance,就像你看到的那样。
但是,我强烈建议您考虑使用IoC框架来解决此问题。
回复:您的评论:
您不能将CustomerEntityManager转换为IEntityManager,因为它不是它实现的 - 它只实现IEntityManager。如果允许演员表,那么类型安全将被打破(当实施明确期望客户,或者至少是合同所说的那样时,您可以传递BusinessEntity。(Co / contra方差可以挽救您)这里因为T进出IEntityManager)。
答案 1 :(得分:1)
忘记使用自己的低级反射,很多不太方便的工作。如果可以,请使用IoC框架,即StructureMap。使用StructureMap,您只需要创建一个知道所有依赖项的注册表(例如CustomersEntityManager
是IEntityManager<Customer>
的实现)。它看起来更像是:
For<IEntityManager<Customer>>().Use<CustomersEntityManager>()
现在,如果您向StructureMap容器询问IEntityManager<Customer>
的实现,那么您将获得CustomersEntityManager
:
ObjectFactory.GetInstance<IEntityManager<Customer>>(); // will return instance of CustomersEntityManager
如果在编译时不知道请求的类型,可以使用普通Type
实例请求实体管理器:
string entityName = "Customer";
Type entityType = Type.GetType(entityType);
Type requestedType = typeof(IEntityManager<>).MakeGenericType(new[] { entityType });
ObjectFactory.GetInstance(requestedType); // will also return CustomersEntityManager instance
可以在程序集中定义注册表,而无需触及业务程序集。
答案 2 :(得分:0)
Object o = Activator.CreateInstance (asm.FullName, EntityName );
会为您提供Customer
的实例。我不确定你会如何从Customer
转到CustomerEntity
,但我相信你可以解决这个问题。