2008-12-08 70 views
4

我正在使用一个通用的存储库接口,它允许我添加,查找,更新和删除不同类型的对象。然后,我实现了两个具体的存储库,并可以在不更改应用程序的情况下切换它们。一切都完美地断开连接。但我遇到了一个障碍。我的存储库方法中的代码只是感觉不对,我无法弄清楚如何更好地做到这一点。这里是我的代码片段:.net体系结构:创建一个IRepository <T>一般

public class OracleRepository<T> : IRepository<T> where T : new() 
{ 
    public IQueryable<T> GetAll() 
    { 
     if (typeof(T) == typeof(Object1)) 
     { 
      return (IQueryable<T>)DataAccess.GetAllObject1().AsQueryable(); 

     } 

     if (typeof(T) == typeof(Object2)) 
     { 
      return (IQueryable<T>)DataAccess.GetAllObject2().AsQueryable(); 
     } 

     throw new NotImplementedException(); 
    } 
} 

的问题是,我的数据访问(从DataReader创建对象)是不是通用的,每种类型的对象,它支持特定的方法。

我可以重写上面的内容,以避免if-then-elseif使用泛型或其他方式的列表吗?

+0

不是更简单的答案是从DataAccess返回一个对象(传递类型或其他)或使用NHibernate或Linq To SQL? – gcores 2008-12-08 11:53:37

回答

11

一种常见模式是使用从类型到相关类型的函数的字典。例如:

private static readonly IDictionary<Type, Func<object>> Fetchers = 
    new Dictionary<Type, Func<object>>(); 
    { 
     (typeof(Object1),() => DataAccess.GetAllObject1().AsQueryable()), 
     (typeof(Object2),() => DataAccess.GetAllObject2().AsQueryable()), 
     // etc 
    }; 

public IQueryable<T> GetAll() 
{ 
    Func<object> func = Fetchers[typeof(T)]; 
    if (func == null) 
    { 
     throw new NotImplementedException(); 
    } 
    return (IQueryable<T>) func(); 
} 

演员阵容,因为你不能真正表达了字典中的类型的关系,但至少它是稍微容易增加新类型等

您可以移动AsQueryable()GetAll()的呼叫取决于GetAllObject1()等返回的值。