且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

具有服务层的存储库和 UoW 模式

更新时间:2022-11-04 22:28:51

不要使用你的 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.