我正在开发一个 MVC 应用程序,我正在使用 Unity 实现 IoC。我的应用程序基本上由 UI 层、服务层和存储库层组成。
我的典型 Controller 是:
public class TestController : Controller
{
private ITestService testServ;
public TestController(ITestService _testServ)
{
testServ= _testServ;
}
public ActionResult Index()
{
testServ.DoSomething();
return View();
}
}
没有什么不寻常的,我的每个 Controller 都注入(inject)了一个服务对象。因此,我的服务层对象执行复杂的业务规则,聚合来自许多不同存储库的信息。通过使用 IoC,我发现我的构造函数看起来过于复杂,但由于该服务需要访问许多存储库,所以我看不出有任何解决方法。
我的服务层中的典型类如下所示:
public class TestService : ITestService
{
private ITransactionRepository transRepo;
private IAccountRepository accountRepo;
private ISystemsRepository sysRepo;
private IScheduleRepository schRepo;
private IProfileRepository profileRepo;
public TestService(ITransactionRepository _transRepo;
IAccountRepository _accountRepo;
ISystemsRepository _sysRepo;
IScheduleRepository _schRepo;
IProfileRepository _profileRepo)
{
transRepo = _transRepo;
accountRepo = _accountRepo;
sysRepo = _sysRepo;
schRepo = _schRepo;
profileRepo = _profileRepo;
}
public DoSomething()
{
//Implement Business Logix
}
}
我的几个服务层对象需要 10 个或更多存储库。我的存储库使用 Entity Framework ,其中每个存储库类在底层数据存储中公开一个表。
我正在寻找有关在上述情况下最佳实践的一些建议。
您已经创建了一个服务层,以便它充当底层存储库的外观。这种方法是一种很好的做法,可以通过粗略的 API 为客户端提供外观。客户不必担心底层存储库。
由于 DI 的完成方式,服务本身现在有一个复杂的构造函数。另一种方法是在 Service 层使用抽象工厂模式并进行 setter 注入(inject)。这种更新存储库的复杂性被转移到一个单独的类中,一个它自己的工厂。
例如:
您可以如下设置测试服务的存储库,而不是构造函数
public class TestService : ITestService
{
private ITransactionRepository transRepo = DataAccess.transRepo;
private IAccountRepository accountRepo = DataAccess.accountRepo;
private ISystemsRepository sysRepo = DataAccess.sysRepo;
private IScheduleRepository schRepo = DataAccess.schRepo ;
private IProfileRepository profileRepo = DataAccess.profileRepo;
}
下面是一个工厂接口(interface)的例子
public interface IRepoFactory
{
ITransactionRepository TransRepo {get;}
IAccountRepository AccountRepo {get;}
ISystemsRepository SysRepo {get;}
IScheduleRepository SchRepo {get;}
IProfileRepository ProfileRepo {get;}
}
下面是一个将新建所有存储库的具体工厂示例。
public class EfFactory : IRepoFactory
{
public ITransactionRepositry TransRepo { return new TransactionRepository();}
public IAccountRepository AccountRepo {return new AccountRepository();}
public ISystemsRepository SysRepo {return new SystemRepository();}
public IScheduleRepository SchRepo {return new SchRepository();}
public IProfileRepository ProfileRepo {return new ProfileRepository();}
}
下面是一个将返回具体工厂的工厂方法(在您的情况下,它将是一个 EF 工厂)
public class RepoFactories
{
public static IRepoFactory GetFactory(string typeOfFactory)
{
return (IRepoFactory)Activator.CreateInstance(Type.GetTypetypeOfFactory)
}
}
具有静态方法的抽象工厂来更新和返回存储库对象
//示例:factoryName = MyProject.Data.EFFactory(这可以添加到您的web.config 或app.config 中)
Public static class DataAccess
{
private static readonly string DbfactoryName= ConfigurationManager.AppSettings.Get("factoryName");
private static readonly IRepoFactory factory = RepoFactories.GetFactory(DbfactoryName);
public static ITransactionRepositry transRepo
{
get {return factory.TransRepo;}
}
public static IAccountRepository accountRepo
{
get {return factory.AccountRepo;}
}
}