我有一个包含以下项目的分层应用程序:
基本存储库如下所示:
public abstract class RepositoryBase<T> where T : class
{
private readonly MyContext context;
private readonly IDbSet<T> dbSet;
protected RepositoryBase(MyContext dataContext)
{
context = dataContext;
dbSet = context.Set<T>();
}
protected MyContext Context
{
get { return context; }
}
**And a series of virtual methods for Add, Delete, etc.
}
所有存储库都扩展了这个存储库,例如:
public class MarketRepository : RepositoryBase<Market>
{
public MarketRepository(MyContext dataContext) : base(dataContext)
{
}
public IEnumerable<Market> GetAllMarkets()
{
return this.Context.Markets.ToList<Market>();
}
}
服务看起来像这样:
public class MarketService
{
IMarketRepository _marketRepository;
public MarketService(IMarketRepository marketRepository)
{
_marketRepository = marketRepository;
}
public IEnumerable<Market> GetAllMarkets()
{
return _marketRepository.GetAllMarkets();
}
}
我想要实现的是UI层只有一个引用服务层,服务层只有DAL层(所有这些都是模型,实体所在的地方)使用DI(现在我正在使用Unity)。
问题是,在我的UI容器中我只想这样做
unity.RegisterType<IMarketService, MarketService>();
并且不必为存储库执行此操作,因为UI层将依赖于DAL层。
我考虑过将无参数构造函数添加到Service类中,例如:
public MarketService() : this(new MarketRepository(*What would I put here?)) { }
但是我失去了界面给出的抽象,而且我不知道如何处理存储库需要的MyContext作为参数;如果我通过一个新的,那么我需要引用DAL。
我是否应该更改我的存储库以在构造函数中创建新的MyContext,而不是将其作为参数?
如何重构我的架构以使其正常工作且依赖性最小?
答案 0 :(得分:1)
嗯,我相信在应用程序的更高级别,由引导程序来配置依赖项。因为它通常是UI项目,如果它需要引用其他程序集,那就这样吧。如果您不喜欢管理它的UI项目,那么创建一个引导程序项目,负责让您的应用程序运行并在另一个项目中分离您的UI类。
答案 1 :(得分:0)
您的IoC容器应使用外部配置文件中的字符串支持依赖注入。这样您就不会对映射进行硬编码。 Structuremap做得很好,所以我相信其他的IoC会。
答案 2 :(得分:0)
在创建实例时添加外部依赖项作为参数是可行的方法 我认为你应该让自己更熟悉配置Unity的不同方法,以便解决依赖关系 您能否详细说明在使用依赖注入框架时创建存储库的原因?
答案 3 :(得分:0)
配置DI时,您应该遵循相同的模式 - UI引导程序初始化服务,服务初始化DAL。 (使用autofac或ninject,您可以使用模块实现此目的。使用unity,您应该模拟模块。)
在伪代码中
//ui
void UILayer.ConfigureUnity(unity)
{
ServiceLayer.ConfigureUnity(unity)
}
//services
void ServiceLayer.ConfigureUnity(unity)
{
DAL.ConfigureUnity(unity)
unity.RegisterType<IMarketService, MarketService>();
}
//dal
void DAL.ConfigureUnity(unity)
{
unity.RegisterType<IMarketRepository, MarketRespository>();
unity.RegisterType<MyContext, MyContext>(); //not sure exact syntax - just register type for 'new Type()' activator.
}