存储库模式,一个接口,多个类

时间:2010-06-29 15:22:40

标签: c#

鉴于此代码

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();
    }
}

你会做些什么来支持许多对象类型(除了Product,另外20种类型,如插件,扩展,页面,部分等)?对于所有对象类型,接口的实现是相同的,唯一不同的是RelativePath - 我们希望将不同类型保存到按类型名称组织的不同文件夹中,如此

  • 〜/数据/产品/...
  • 〜/数据/插件/...
  • 〜/数据/页/...

因此,假设唯一改变的是路径。显然,我们不希望为每个对象类型创建一个存储库类,并将相同的代码复制到每个类中。我们只想根据用于T的对象构造路径。 / p>

3 个答案:

答案 0 :(得分: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();
    }
}

答案 1 :(得分: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(); 
} 

}

答案 2 :(得分: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();
    }
}

不幸的是,您需要指定 ProductCollection - &gt;实现 GetAll()。如果没有此 ProductCollection ,您也可以将 GetAll()方法移动到基类。