2011-06-20 134 views
3

我有一个业务逻辑组件以下实现一个通用的接口:实例化一个类使用反射

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. 
    } 
} 

我可以选择修改业务程序集。但实例创建需要在我当前的项目中,我必须使用反射来加载业务程序集。所有的数据类型只有在运行时才会知道。

我可能会错过一些根本性的东西,或者可能做错了编码。请帮我解决这个问题。

UPDATE:

遵循 “德里斯” 的建议,像以下:

string fullTypeName = "Your.Namespace." + EntityName + "EntityManager"; 
object o = Activator.CreateInstance(asm.FullName, fullTypeName); 

看起来它创建的实例。然而,它结束了一个错误:

Cannot cast 'o' (which has an actual type of 'CustomerEntityManager') to 'IEntityManager'

时得到执行以下语句:

return o as IEntityManager<BusinessEntity> 

感谢

回答

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)

+0

+1 for IoC Framework – smartcaveman

+0

driis,我得到错误当语句“return o as IEntityManager ”时,无法将'o'(具有'CustomerEntityManager'的实际类型)转换为'IEntityManager '正在执行。 – user203687

+0

你不想要IEntityManager ?因为这是CustomerEntityManager实现的。 – driis

0

结帐Activator.CreateInstance()

Object o = Activator.CreateInstance (asm.FullName, EntityName); 

会给你一个实例的Customer。我不知道你会如何从CustomerCustomerEntity,但我相信你可以完成这一部分。

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 

注册可以在装配中定义,而不土特产品清商务会议。

+0

感谢您的建议。有没有Microsoft的PnP实现这样的? – user203687

+0

是的,它被称为Unity - http://msdn.microsoft.com/en-us/library/ff663144.aspx - 它通常应该可以做同样的事情,但是你必须自己阅读,因为我不喜欢我不太了解Unity。 – NOtherDev

+0

非常感谢 – user203687

相关问题