我正在创建一个类库API,它通过Entity Framework 6包装业务逻辑和访问SQL Server数据库。
我使用工作单元和存储库模式设计了它。 目的是使其易于使用和单元测试。
将在服务层执行业务逻辑和验证。 我不会使用IOC容器,因为我觉得它会使API复杂化 的使用。
该项目有15个存储库和服务
目前的设计如下:
服务层A - >工作单位 - >存储库A和/或B
服务层B - >工作单位 - >存储库B和/或A ...
...
public class ServiceA : IServiceA, IService
{
private readonly IUnitOfWork unitOfWork;
public AssetService(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
}
...
public IList<DomainObjectA> GetAll()
{
return unitOfWork.RepositoryA.GetAll();
}
public void Dispose()
{
unitOfWork.Dispose();
}
...
}
public class UnitOfWork : IUnitOfWork
{
private readonly MyDbContext context = new MyDbContext();
private IRepositoryA repositoryA;
private IRepositoryB repositoryB;
...
public IRepositoryA RepositoryA
{
get { return repositoryA = repositoryA ?? new RepositoryA(context); }
}
public IRepositoryB RepositoryB
{
get { return repositoryB = repositoryB ?? new RepositoryB(context); }
}
...
public void Save()
{
context.SaveChanges();
}
public void Dispose()
{
context.Dispose();
}
}
public class RepositoryA : Repository, IRepositoryA
{
public RepositoryA(MyDbContext context)
: base(context) {}
public IList<DomainObjectA> GetAll()
{
return context.tblA.ToList().Select(x => x.ToDomainObject()).ToList();
}
...
}
由于这是一个应该由其他项目使用的API,因此我需要为使用API的用户提供一个漂亮且“相当”易于使用的界面。 因此,UnitOfWork是在用户和服务层之间的“公共接口”中创建的,见下文。
我还认为最好将using语句放在API中,以便在每次服务调用之后立即正确地处理db-context。
我开始使用代理模式: 例如:
public class ProxyA : Proxy, IServiceA
{
public IList<DomainObjectA> GetAll()
{
using (var service = GetService<ServiceA>())
return service.GetAll();
}
...
}
public abstract class Proxy
{
protected T GetService<T>() where T : IService
{
return (T)Activator.CreateInstance(typeof(T), new object[] { new UnitOfWork()});
}
}
但是这需要我为每个服务创建一个代理。我当然可以跳过代理中的服务接口,并创建一个处理所有服务的公共代理。
我还查看了Facade模式,但无法确定在这种情况下使用哪种模式。
我的问题:
这是一个好方法还是有其他设计模式可以解决这个问题?
此外,是否应该有一个或多个公共API入口点,按一些业务逻辑分组?
答案 0 :(得分:0)
我认为您的设计和使用的模式没有任何问题。
关于代理模式,如果您想要使用它,那么它就是您的呼叫。正如您所提到的,您必须创建锅炉板代码以为每项服务创建一个。如果您只想隐藏对db服务的调用,或者您希望每次调用该服务时都添加该行代码(并确保执行此操作以避免泄漏),那么它是有争议的。此外,您可能会考虑将来是否需要在代理服务器中添加额外的功能,这将增加额外的权重来创建代理选项。
关于一个或多个入口点,我将创建一个为业务逻辑域分组的ServiceA,ServiceB,ServiceC等(如此)。通常情况下,你会有5到20之间(只是一个近似的数字,以了解幅度)
您可能想要查看支持此想法的界面隔离原则
http://en.wikipedia.org/wiki/Interface_segregation_principle