2014-11-03 67 views
0

仅供参考:详细的序言部分有助于解释我为什么使用Activator.CreateInstance。我有许多实体(对应于数据库列信息的对象)“包含”在多个数据库中,每个数据库都有不同的表/列设置。所以我能够从每个数据库检索一个实体,但检索它的方式因数据库而异。直到运行时才会知道数据库类型,并可能在整个执行过程中有所不同我创建了以下设置:C#Activator.CreateInstance通用实例迷路

首先定义每个实体应支持的查询操作,每个实体读取器应支持这些操作。

public abstract class Operations<T> { 
    public delegate T findDelegate(int id); 
    public findDelegate find; 
} 

// there are many of these N=1,2,..., but here is one 
// use abstract class since implementation of queries should be done by handlers 
public class EntityNReader : Operations<EntityN> { 
    public Reader(); 
} 

定义“Handler”类的接口,即这些类实现上面列出的查询操作。

public interface IHandler<T> { 
    public string find(int id); 
} 

// there are many of these N,M=1,2..., but here is one 
// use of interface is to force handlers to implement all query types 
public class EntityNHandlerForDbTypeM : IHandler<EntityN> { 
    public string find(int id) {/*whatever*/} 
} 

这使得开发人员能够创建一个类来处理EntityN查询操作为DbTypeM。现在,创建一个Database类,其中包含读者对象并将处理器方法绑定到读者代表。

public class Database { 
    // there are many of these, but here is one 
    public EntityNReader EntitiesN; 

    public Database(string dbType) { 
     // this is called for each EntityNReader 
     bindHandlers<Reader, TypeN>(MyReader, dbType); 
     // ... 

     // nullreferenceexception 
     EntitiesN.find(0); 
    } 

    // this is a factory that also performs late binding 
    private void bindHandlers<T,K>(T reader, string dbTypeM) 
     where T: Operations<K>, new() 
    { 
     // create instance of EntityNReader 
     r = (T)Activator.CreateInstance(typeof(T)); 
     // r != null 

     // create instance of handler 
     IHandler<K> h = (IHandler<K>)(Activator.CreateInstance(
      Type.GetType("namespace.to.EntityNHandlerForDbTypeM"), 
      new object[] { this } 
     )); 

     // bind delegates 
     r.find = h.find; 
    } 
} 

正如你在Database的构造函数看到,编写代码的方式,现在,我得到一个NullReferenceException纵然EntityNReaderr创建实例,(验证为)NOT NULL。

但是,如果我实例化EntitiesN它在Database而不是在bindHandlers中声明,代码编译和一切正常。我不只是这样做的原因是(随后)我想在实例化Database类时有条件地在bindHandlers内创建读者/处理程序。

这里发生了什么? Link to actual code if necessary. P.S.我对编程相对来说比较陌生,所以我很乐于听到一位体验开发人员如何设计这个组件(特别是如果我正走向错误的道路)。

回答

0

我知道你的代码只是样品,但我发现这个马上蝙蝠...

if (supports[typeof(Entity1).Name]) { bindHandlers<Entity1Reader, Entity1>(Entities1, CamaDbType); } 
if (supports[typeof(Entity2).Name]) { bindHandlers<Entity1Reader, Entity1>(Entities1, CamaDbType); } 

有没有可能是你有一个简单的复制/粘贴错误?请注意Entity1被传递给bindHandlers调用。

+0

没有抱歉。我注意到,修正了它,并没有将更改推送到github(对不起)。上面的问题出现在我做出改变之后。我只是推动了这些变化。 – jayflo 2014-11-03 14:19:09