Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/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# 带有服务层的存储库和UoW模式_C#_Repository Pattern_Unit Of Work - Fatal编程技术网

C# 带有服务层的存储库和UoW模式

C# 带有服务层的存储库和UoW模式,c#,repository-pattern,unit-of-work,C#,Repository Pattern,Unit Of Work,我正在使用存储库和UoW模式。我的服务如下所示: public class MyService : IService { private readonly IUnitOfWork<MyContext> unitOfWork; private readonly IMyRepository myRepository; public MyService(IUnitOfWork<MyContext> unitOfWork, IMyRepository m

我正在使用存储库和UoW模式。我的服务如下所示:

public class MyService : IService
{
    private readonly IUnitOfWork<MyContext> unitOfWork;
    private readonly IMyRepository myRepository;

    public MyService(IUnitOfWork<MyContext> unitOfWork, IMyRepository myRepository)
    {
        this.unitOfWork = unitOfWork;
        this.myRepository = myRepository;
    }

    //Methods...
}
公共类MyService:IService
{
私有只读IUnitOfWork;
私有只读IMyRepository myRepository;
公共MyService(IUnitOfWork、IMyRepository myRepository)
{
this.unitOfWork=unitOfWork;
this.myRepository=myRepository;
}
//方法。。。
}
在服务中,我需要使用其他实体(例如检查权限等)

建议使用服务中的相关存储库还是直接使用服务

此外,对于每个用户,我们对每个CRUD操作都有权限(布尔值)。这些权限存储在数据库中


权限检查应该在控制器级别还是在服务级别进行?

我认为使用存储库很好。我不会为每个repo发明一个服务层。
存储库用于抽象数据访问,服务层用于封装业务逻辑,但随着最近的趋势,我发现这有点过头了。如果服务层充当控制器,但不要尝试将一对一映射到每个实体或repo,那么使用服务层就可以了。

我认为使用存储库就可以了。我不会为每个repo发明一个服务层。 存储库用于抽象数据访问,服务层用于封装业务逻辑,但随着最近的趋势,我发现这有点过头了。如果服务层充当控制器,但不要试图将一对一映射到每个实体或回购,则使用服务层是可以的。

我的黄金法则是:

当您在UI中获得业务逻辑时,创建一个服务,否则使用 直接访问存储库

因此,如果用户界面中有以下代码:

var user = repos.Get(1);
user.FirstName = txtFirstName.Text;
repos.Save(user);
我认为你很好。但如果你有类似的东西:

var user = userRepository.Get(1);
var accessChecker = authorizationRepository.GetForUser(id);
if (!accessChecker.MaySendEmail(user))
    throw new SecurityException("You may not send emails");

var emailSender = new EmailSenderService();
emailSender.Send(user, txtDestination.Text, txtMessage.Text);
repos.Save(user);
您很可能应该改用服务。

我的金科玉律是:

当您在UI中获得业务逻辑时,创建一个服务,否则使用 直接访问存储库

因此,如果用户界面中有以下代码:

var user = repos.Get(1);
user.FirstName = txtFirstName.Text;
repos.Save(user);
我认为你很好。但如果你有类似的东西:

var user = userRepository.Get(1);
var accessChecker = authorizationRepository.GetForUser(id);
if (!accessChecker.MaySendEmail(user))
    throw new SecurityException("You may not send emails");

var emailSender = new EmailSenderService();
emailSender.Send(user, txtDestination.Text, txtMessage.Text);
repos.Save(user);

您可能应该改用服务。

不要使用UoW来包装数据库上下文。由于您的所有存储库都直接依赖于给定的上下文(或多或少,ofc),因此您的存储库可以包含在UoW中。大致如下:

public interface IUnitOfWork<TContext> : IDisposable { }

public abstract class UnitOfWork<TContext> : IUnitOfWork<TContext> {

    private readonly TContext _context;
    protected TContext Context { get{ return _context; } }

    protected UnitOfWork(TContext context){
        _context = context;
    }
}

public interface IMyDbUnitOfWork : IUnitOfWork<MyContext>{

    public ICarRepository Cars { get; }
    public IOwnerRepository Owners { get; }

}

public class MyDbUnitOfWork : UnitOfWork<MyContext>, IMyDbUnitOfWork{

    public MyDbUnitOfWork():base(new MyContext()){}

    private ICarRepository _cars;
    public ICarRepository Cars { 
        get{
            return _cars ?? (_cars = new CarRepository(Context));
        }
    }

    private ICarRepository _owners;
    public IOwnerRepository Owners { 
        get{
            return _owners ?? (_owners = new OwnerRepository(Context));
        }
    }

}


public class MyService : IService
{
    private readonly IMyDbUnitOfWork _unitOfWork;

    public MyService(IMyDbUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    //Methods...
}
公共接口IUnitOfWork:IDisposable{}
公共抽象类UnitOfWork:IUnitOfWork{
私有只读TContext\u上下文;
受保护的TContext上下文{get{return}
受保护的UnitOfWork(TContext上下文){
_上下文=上下文;
}
}
公共接口IMyDbUnitOfWork:IUnitOfWork{
公共电子储蓄车{get;}
公共IOOwnerRepository所有者{get;}
}
公共类MyDbUnitOfWork:UnitOfWork,IMyDbUnitOfWork{
公共MyDbUnitOfWork():基(新MyContext()){}
私家车;
公共储蓄车{
得到{
归还车辆??(\u车辆=新的运输地点(上下文));
}
}
私人Icarepository所有者;
公共所有权或保留所有权人{
得到{
返回_owners???(_owners=newownerrepository(上下文));
}
}
}
公共类MyService:IService
{
私有只读IMyDbUnitOfWork(单位工作);;
公共MyService(IMyDbUnitOfWork unitOfWork)
{
_unitOfWork=unitOfWork;
}
//方法。。。
}
很明显,你可以创建这个或多或少的通用,但我相信这应该足以通过我的观点。 值得注意的是,由于我通常使用IoC框架,我的服务会收到
IUnitOfWorkFactory
,因为生活方式不同

对于权限问题,这实际上取决于您希望拥有多少控制权,以及您希望应用程序对用户的友好程度。通常是两者的混合。你的应用程序应该知道你的用户是否有权访问屏幕,但也知道你是否必须相应地禁用按钮。由于您还必须防止这种情况,如果用户出于任何原因可以调用您的服务方法,那么您不能允许它。
为了解决这个问题,我不按CRUD操作进行过滤,而是按服务操作进行过滤,拦截每个服务调用,这使得将我的权限映射到用户界面很容易,因为按钮操作和服务操作之间通常是1:1的关系。

不要使用UoW来包装数据库上下文。由于您的所有存储库都直接依赖于给定的上下文(或多或少,ofc),因此您的存储库可以包含在UoW中。大致如下:

public interface IUnitOfWork<TContext> : IDisposable { }

public abstract class UnitOfWork<TContext> : IUnitOfWork<TContext> {

    private readonly TContext _context;
    protected TContext Context { get{ return _context; } }

    protected UnitOfWork(TContext context){
        _context = context;
    }
}

public interface IMyDbUnitOfWork : IUnitOfWork<MyContext>{

    public ICarRepository Cars { get; }
    public IOwnerRepository Owners { get; }

}

public class MyDbUnitOfWork : UnitOfWork<MyContext>, IMyDbUnitOfWork{

    public MyDbUnitOfWork():base(new MyContext()){}

    private ICarRepository _cars;
    public ICarRepository Cars { 
        get{
            return _cars ?? (_cars = new CarRepository(Context));
        }
    }

    private ICarRepository _owners;
    public IOwnerRepository Owners { 
        get{
            return _owners ?? (_owners = new OwnerRepository(Context));
        }
    }

}


public class MyService : IService
{
    private readonly IMyDbUnitOfWork _unitOfWork;

    public MyService(IMyDbUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }

    //Methods...
}
公共接口IUnitOfWork:IDisposable{}
公共抽象类UnitOfWork:IUnitOfWork{
私有只读TContext\u上下文;
受保护的TContext上下文{get{return}
受保护的UnitOfWork(TContext上下文){
_上下文=上下文;
}
}
公共接口IMyDbUnitOfWork:IUnitOfWork{
公共电子储蓄车{get;}
公共IOOwnerRepository所有者{get;}
}
公共类MyDbUnitOfWork:UnitOfWork,IMyDbUnitOfWork{
公共MyDbUnitOfWork():基(新MyContext()){}
私家车;
公共储蓄车{
得到{
归还车辆??(\u车辆=新的运输地点(上下文));
}
}
私人Icarepository所有者;
公共所有权或保留所有权人{
得到{
返回_owners???(_owners=newownerrepository(上下文));
}
}
}
公共类MyService:IService
{
私有只读IMyDbUnitOfWork(单位工作);;
公共MyService(IMyDbUnitOfWork unitOfWork)
{
_unitOfWork=unitOfWork;
}
//方法。。。
}
很明显,你可以创建这个或多或少的通用,但我相信这应该足以通过我的观点。 值得注意的是,由于我通常使用IoC框架,我的服务会收到
IUnitOfWorkFactory
,因为生活方式不同

为了