API入口点的设计模式?

时间:2014-01-17 16:07:32

标签: c# design-patterns dependency-injection entity-framework-6 api-design

我正在创建一个类库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入口点,按一些业务逻辑分组?

1 个答案:

答案 0 :(得分:0)

我认为您的设计和使用的模式没有任何问题。

关于代理模式,如果您想要使用它,那么它就是您的呼叫。正如您所提到的,您必须创建锅炉板代码以为每项服务创建一个。如果您只想隐藏对db服务的调用,或者您希望每次调用该服务时都添加该行代码(并确保执行此操作以避免泄漏),那么它是有争议的。此外,您可能会考虑将来是否需要在代理服务器中添加额外的功能,这将增加额外的权重来创建代理选项。

关于一个或多个入口点,我将创建一个为业务逻辑域分组的ServiceA,ServiceB,ServiceC等(如此)。通常情况下,你会有5到20之间(只是一个近似的数字,以了解幅度)

您可能想要查看支持此想法的界面隔离原则

http://en.wikipedia.org/wiki/Interface_segregation_principle