默认存储库类的扩展

时间:2011-04-26 00:59:13

标签: c# .net entity-framework

我正在使用带有接口的存储库模式,我正在使用structuremap来映射它们。

在我的global.asax中,我定义了:

    ObjectFactory.Initialize(x =>
        {
            x.For<IUnitOfWorkFactory>().Use<EFUnitOfWorkFactory>();
            x.For(typeof(IRepository<>)).Use(typeof(EFRepository<>)
        }
    );

现在我想向MyEntity实体添加另一个db方法。所以我创建了MyEntityRepository:

class MyEntityRepository:EFRepository<MyEntity>, IMyEntityRepository {
    public void CloseCall(long callId) {
        ....
        ....
    }
}

但是现在,我不得不在structmap的初始化中添加一个新行。我有很多这样的情况,结构图初始化中的行数越来越大。

此外,大多数情况只是一个方法添加,但这个单一方法添加需要新存储库的接口,新文件中的实现和结构图的另一个初始化 - 一个方法的很多工作。

我该如何解决这个问题?

我做错了吗?

也许最好将扩展metod用于Repository(如果有这样的东西扩展到泛型......)?

2 个答案:

答案 0 :(得分:0)

如果您有必须使用特殊类型解析的特殊接口,则必须始终在某处编写代码以初始化它。如果您不想在StructureMap初始化中编写太多代码,请使用DAL层的抽象工厂模式:

工厂界面:

public interface IDalFactory
{
    IXXXRepository XXXRepository { get; }
    IYYYRepository YYYRepository { get; }
} 

实现:

public class DalFactory : IDalFactory
{
    private IXXXRepository _xxxRepository;
    public IXXXRepository XXXRepository
    {
        return _xxxRepository ?? (_xxxRepository = new XXXRepository());
    }

    private IYYYRepository _yyyRepository;
    public IYYYRepository YYYRepository
    {
        return _yyyRepository ?? (_yyyRepository = new YYYRepository());
    }
}

您将初始化您的IoC:

ObjectFactory.Initialize(x =>
        {
            x.For<IUnitOfWorkFactory>().Use<EFUnitOfWorkFactory>();
            x.For<IDalFactory>().Use<DalFactory>();
        }
    );

专门的代码总是需要在某处进行自己的注册,除非你构建一些自动注册,它将使用反射搜索你的程序集并通过一些命名约定来注册存储库。

答案 1 :(得分:0)

在我的业务层 - 我定义了我创建的IRepository接口:

public abstract class BaseRepository<T> : IRepository<T> where T : IDataEntity
{
    protected IRepository<T> Repository { get; set; }

    public BaseRepository()
    {
        Repository = ObjectFactory.GetInstance<IRepository<T>>();
    }

    public virtual IQueryable<T> GetQuery()
    {
        return Repository.GetQuery();
    }

    public virtual IQueryable<T> GetQuery(params Expression<Func<T, object>>[] includes)
    {
        return Repository.GetQuery(includes);
    }

    public virtual void Insert(T entity)
    {
        Repository.Insert(entity);
    }

    public virtual void Update(T entity)
    {
        Repository.Update(entity);
    }

    public virtual void Delete(T entity)
    {
        Repository.Delete(entity);
    }

    public virtual void Attach(T entity)
    {
        Repository.Attach(entity);
    }
}

在global.asax中,我必须将IRepository映射到实体框架实现 现在,对于我想要暴露给网络的每个类,我必须定义:

public class MyEntityRepository: BaseRepository<MyEntity> {
    ....
    Common queries for this entity
    ....
    ....
    overrides of insert, delete and so on
}

现在,我根本不能在Web应用程序中使用BaseRepository,而是使用属于该实体的存储库。我也不需要在structuremap中注册存储库的每个扩展。唯一的问题是我必须记住不要直接使用EFRepository(我可以使用结构图来获取它 - 我必须避免使用它)。