2014-03-19 70 views
0

我正在使用Repository和UoW模式。我的服务如下所示:存储库和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... 
} 

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

是否建议在服务中使用相关存储库或直接使用服务?

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

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

回答

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

显然你可以创建这个或多或少的泛型,但我相信这应该足以通过我的观点。 作为一个说明,由于我通常使用IoC框架,我的服务因为不同的生活方式而收到IUnitOfWorkFactory

对于权限问题,它确实取决于您想要拥有多少控制权以及您希望自己的应用程序的用户友好程度。通常是两者的混合。您的应用程序应该知道您的用户是否可以访问该屏幕,但是也必须相应地禁用按钮。既然你也必须阻止,如果由于任何原因,用户可以调用你的服务方法,你不能允许它。 要解决此问题,我不会通过CRUD操作进行筛选,而是通过服务操作来拦截每个服务调用,这使得我的权限可以轻松映射到用户界面,因为通常是按钮操作和服务操作之间的1对1关系。

+0

使用UoW存储库的想法很好,但是ma数据库有100个实体。另一方面,我的每个服务都会得到一个新的UoW(因此是新的dbcontext),并且很难为不同的服务维护相同的上下文。 –

+0

这就是我使用IUnitOfWorkFactory的原因。我可以用它来管理生命周期,例如,我可以很轻松地保证,在同一个Web请求中调用的每个服务都会收到相同的UnitOfWork。 –

0

我认为使用存储库就好了。我不会为每个回购协议发明一个服务层。 存储库用于抽象数据访问,服务层用于封装业务逻辑,但是随着近期的趋势,我发现这种矫枉过正。如果服务层充当控制器,但没有尝试将一对一映射到每个实体或回购,那么拥有服务层就没有问题。

4

我的金科玉律是:

当你在你的UI的业务逻辑创建服务,否则直接使用 库。

所以,如果你有这样的代码在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); 

您很可能应该使用服务。

0

我通常使用来自用户界面的服务,这些服务反过来使用存储库。我还发现有一些域对象封装了服务中的可重用逻辑。

我这样做是为了让服务不用调用对方并获得循环引用,而是使用通用的域对象。这样可以避免循环引用和人们在同一地点复制和粘贴相同的代码。如果需要,此域对象可能会使用这些存储库。