Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# API入口点的设计模式?_C#_Design Patterns_Dependency Injection_Entity Framework 6_Api Design - Fatal编程技术网

C# API入口点的设计模式?

C# API入口点的设计模式?,c#,design-patterns,dependency-injection,entity-framework-6,api-design,C#,Design Patterns,Dependency Injection,Entity Framework 6,Api Design,我正在创建一个类库API,它封装了业务逻辑并通过EntityFramework6访问SQLServer数据库 我使用工作单元和存储库模式设计了它。 目的是使其易于使用和单元测试 业务逻辑和验证将在服务层中执行。 我不会使用IOC容器,因为我觉得它会使API复杂化 用法 该项目有15个存储库和服务 目前的设计如下: 服务层A->工作单元->存储库A和/或B 服务层B->工作单元->存储库B和/或A。。。 因为这是一个应该被其他项目使用的API,所以我需要为使用该API的用户提供一个漂亮且易于使用

我正在创建一个类库API,它封装了业务逻辑并通过EntityFramework6访问SQLServer数据库

我使用工作单元和存储库模式设计了它。 目的是使其易于使用和单元测试

业务逻辑和验证将在服务层中执行。 我不会使用IOC容器,因为我觉得它会使API复杂化 用法

该项目有15个存储库和服务

目前的设计如下:

服务层A->工作单元->存储库A和/或B 服务层B->工作单元->存储库B和/或A。。。

因为这是一个应该被其他项目使用的API,所以我需要为使用该API的用户提供一个漂亮且易于使用的界面。 因此,UnitOfWork是在用户和服务层之间的公共接口中创建的,请参见下文

我还认为最好将using语句放在API中,以便在每次服务调用之后立即正确地处理db上下文

我开始使用代理模式进行此操作: 例如:

但这需要我为每个服务创建一个代理。当然,我可以跳过代理中的服务接口,创建一个处理所有服务的公共代理

我还研究了Facade模式,但无法决定在这个特定场景中使用哪种模式

我的问题是: 这是一个好方法还是有其他设计模式可以解决这个问题


另外,是否应该有一个或多个公共API入口点,根据一些业务逻辑进行分组?

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

关于代理模式,如果您想使用或不使用它,这是您的决定。正如您所提到的,您必须创建锅炉板代码来为每个服务创建一个。如果您只想使用它来隐藏对db服务的调用,或者希望在每次调用该服务时添加该行代码,并确保这样做是为了避免泄漏,那么这是有争议的。此外,您可能会考虑将来是否需要在代理中添加额外的功能,这将增加额外的权重来创建代理选项。 关于一个或多个入口点,我将创建一个ServiceA、ServiceB、ServiceC等,以便为业务逻辑域分组。通常情况下,你会有5-20个,只是一个大概的数字,给出一个大小的想法

您可能需要回顾支持此想法的接口隔离原则


那么,您是说,创建更少的按业务逻辑分组的服务,而不是为每个存储库创建一个服务,然后将代理模式保持为每个服务一个代理作为api前端?我想我更喜欢这种方法,而不是创建一个包含所有api可用方法的fat facade类……是的,这是我通常使用的方法。创建fat facade的问题在于,随着应用程序的增长,单个类中可能会出现太多的方法。
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();
    }

    ...
}
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()});
    }
}