2010-06-29 86 views
2

鑑於此代碼Repository模式,一個接口,多個類

public interface IRepository<T> 
{ 
    IQueryable<T> GetAll(); 
} 

public class XmlProductRepository : IRepository<Product> 
{ 
    private const string RelativePath = "~/data/products.xml"; 

    public string Filename { get; private set; } 
    public XmlLoader Loader { get; private set; } 

    public XmlProductRepository(HttpContextBase httpContext, XmlLoader loader) 
    { 
     Filename = httpContext.Server.MapPath(RelativePath); 
     Loader = loader; 
    } 

    public IQueryable<Product> GetAll() 
    { 
     return Loader.Load<ProductCollection>(Filename).AsQueryable(); 
    } 
} 

你會做什麼,以支持許多對象類型(除了產品,另外20種喜歡的插件,擴展,頁面,部分等)?該接口的實現是所有對象類型相同,即不同的唯一事情就是RelativePath - 我們要保存不同類型的成他們的類型名稱舉辦不同的文件夾,像這樣

  • 〜/數據/產品/ ...
  • 〜/數據/插件/ ...
  • 〜/數據/頁/ ...

所以假設改變的是路徑的唯一的事。顯然,我們不想爲每個對象類型創建一個存儲庫類,並將相同的代碼複製到每個類中。我們只是想構建基於用於T的對象的路徑。

+0

什麼是* ProductCollection *?似乎我們必須爲每種類型實現* GetAll()*,因爲不同的集合... – tanascius 2010-06-29 15:33:46

+0

不,我們不需要這樣做,因爲這會由執行反序列化的XmlLoader類加載,所以這可以很好地解決。 – mare 2010-06-29 15:43:47

+0

其實你說得對,但這段代碼實際上並不是GetAll()的正確實現。代替ProductCollection,將會有一個基本集合類,所有特定的集合都繼承自它。 – mare 2010-06-29 15:49:19

回答

2

您可以使XmlRepository變得通用並使用typeof來獲取xml文件的名稱嗎?

public class XmlRepository<T> : IRepository<T> 
{ 
    private readonly string RelativePath; 

    public string Filename { get; private set; } 
    public XmlLoader Loader { get; private set; } 

    public XmlRepository(HttpContextBase httpContext, XmlLoader loader) 
    { 
     RelativePath = string.Format("~/data/{0}.xml" + typeof(T).Name); 
     Filename = httpContext.Server.MapPath(RelativePath); 
     Loader = loader; 
    } 

    public IQueryable<T> GetAll() 
    { 
     return Loader.Load<List<T>>(Filename).AsQueryable(); 
    } 
} 
+0

我已經嘗試過這種方式,但是在嘗試使用Ninject for IoC時遇到了一些問題,例如Ninject規則需要這樣寫: Bind >()。()。 InSingletonScope(); 這不起作用 Bind >()。>()。InSingletonScope(); – mare 2010-06-29 15:32:35

+0

您可以從XmlRepository 創建XmlProductRepository,這並不理想,但您的實現將會很少。 – 2010-06-29 15:34:13

+1

如果您創建小包裝,它會起作用嗎?即。 'public class XmlProductsRepository:XmlRepository '? – 2010-06-29 15:35:13

0
public class XmlRepository<TEntityType> : IRepository<TEntityType> 
{ 

Type t = typeof(TEntityType); 
private const string RelativePath = String.Format("~/data/{0}.xml",t.Name); 

public string Filename { get; private set; } 
public XmlLoader Loader { get; private set; } 

public XmlProductRepository(HttpContextBase httpContext, XmlLoader loader) 
{ 
    Filename = httpContext.Server.MapPath(RelativePath); 
    Loader = loader; 
} 

public IQueryable<TEntityType> GetAll() 
{ 
    return Loader.Load<List<TEntityType>>(Filename).AsQueryable(); 
} 

}

0

你可以創建一個抽象基類,如:

public abstract class Repository<T> : IRepository<T> 
{ 
    public string Filename { get; private set; } 
    public XmlLoader Loader { get; private set; } 

    protected Repository<T>(HttpContextBase httpContext, XmlLoader loader, string relativePath) 
    { 
     Filename = httpContext.Server.MapPath(relativePath)); 
     Loader = loader; 
    } 

    public abstract IQueryable<T> GetAll(); 
} 

XmlProductRepository:

public class XmlProductRepository : Repository<Product> 
{ 
    public XmlProductRepository(HttpContextBase httpContext, XmlLoader loader) 
      : base(httpContext, loader, "~/data/products.xml") {} 

    public IQueryable<Product> GetAll() 
    { 
     return Loader.Load<ProductCollection>(Filename).AsQueryable(); 
    } 
} 

不幸的是,看起來,你需要指定Produc tCollection - >實施GetAll()。如果沒有這個ProductCollection您可以將GetAll()方法也移動到基類。

+0

GetAll()只是其中一種方法,會有很多方法,我們不想在不同的文件中重複它們 - 維護地獄和不好的做法。 – mare 2010-06-29 15:40:24