具有服务层的存储库和 UoW 模式 [英] Repository and UoW pattern with service layer

查看:57
本文介绍了具有服务层的存储库和 UoW 模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using Repository and UoW pattern. My services look like this:

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...
}

在服务中,我需要使用其他实体(例如检查权限等).

Within services, I need to use other entities (for example to check for rights, etc).

建议使用服务中的相关仓库还是直接使用服务?

Is it recommended to use the relevant repositories in the service or use the services directly?

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

Also, for each user we have rights (boolean) for each CRUD action. These rights are stored in the database.

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

Should checking of rights be done at the controller level or at the service level?

推荐答案

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

Don't use your UoW to just wrap your database context. Since all your repositories are directly dependent of a given context (more or less, ofc), your repositories can be included in the UoW. Something along the lines of:

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...
}

显然,您可以创建或多或少通用的,但我相信这应该足以通过我的观点.请注意,由于我通常使用 IoC 框架,因此我的服务会因不同的生活方式而收到 IUnitOfWorkFactory.

Obviously you can create this more or less generic, but I believe this should be enough to pass my point. As a note, and since I normally use IoC frameworks, my services receive an IUnitOfWorkFactory because of the diferent lifestyles.

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

For the permissions question, it really depends how much control you want to have and how user friendly you want your application to be. Normally is a mix of both. Your application should know if your user has access to the screen but also if you must disable buttons accordingly. Since you also must prevent that, if by any reason, the user can invoke your service method, you can't allow it. To solve this problem I don't filter by CRUD actions but by Service actions instead, intercepting every service invocation, which makes it easy to map my permissions to the user interface since normally is a 1 to 1 relation between button action and service action.

这篇关于具有服务层的存储库和 UoW 模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆