我将在我的asp.net核心mvc应用程序中实现存储库模式,因为我正在尝试使用包含存储库和工作单元概念的简单演示应用程序。我的第一个存储库
public interface ICustomerRepository
{
bool Add();
bool Update();
bool Delete();
}
和
public class CustomerRepository:ICustomerRepository
{
public bool Add()
{
return true;
}
public bool Update()
{
return true;
}
public bool Delete()
{
return true;
}
}
第二个存储库
public interface IOrderRepository
{
bool Add();
bool Update();
bool Delete();
}
和
public class OrderRepository:IOrderRepository
{
public bool Add()
{
return true;
}
public bool Update()
{
return true;
}
public bool Delete()
{
return true;
}
}
工作单位
public interface IUnitOfWork
{
IOrderRepository Order {get;}
ICustomerRepository Customer { get; }
void Save();
void Cancel();
}
和
public class UnitOfWork:IUnitOfWork
{
public UnitOfWork(IOrderRepository order, ICustomerRepository customer)
{
Order = order;
Customer = customer;
}
public IOrderRepository Order { get; }
public ICustomerRepository Customer { get; }
public void Save() { }
public void Cancel() { }
}
在我的控制器中,
public class HomeController : Controller
{
IUnitOfWork UW { get; }
public HomeController(IUnitOfWork uw)
{
UW = uw;
}
public IActionResult Index()
{
UW.Customer.Add();
UW.Order.Update();
UW.Save();
return View();
}
}
我稍后会为dapper添加更多代码,但至少它应该没有任何错误,但它给了我错误
InvalidOperationException:尝试激活'CoreTS.Controllers.HomeController'时,无法解析类型'CoreTS.Repository.UnitOfWork.IUnitOfWork'的服务。
有人建议我在ConfigureService方法下的startup.cs中添加IUnitOfWork作为服务
services.AddSingleton<IUnitOfWork, UnitOfWork>();
并添加此另一个错误
InvalidOperationException:尝试激活'CoreTS.Repository.UnitOfWork.UnitOfWork'时,无法解析类型'CoreTS.Repository.Order.IOrderRepository'的服务。
为了使它工作,我还必须在startup.cs中添加其他两个存储库
services.AddSingleton<IOrderRepository, OrderRepository>();
services.AddSingleton<ICustomerRepository, CustomerRepository>();
如果存在n个存储库而不是我必须在startup.cs中添加它们的每个(根据此代码),那么解决方案是什么。
所以
1.]这些错误意味着什么?
2.]这里的配置是什么?
3.]在这里不添加n个存储库作为服务的方法是什么?
注意:如前所述,这只是为了理解模式的流程,我将在后面添加Dapper或EF Core的代码
这些错误意味着什么?
这些错误意味着您通过构造函数依赖注入使用服务,但您尚未将这些服务注册到DI解析器。
这里的配置是什么?
您所做的是解决服务的正确方法。
不在此处添加n个存储库作为服务的方法是什么?
您可以在单独的文件中将IServiceCollection
扩展如下。
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddCustomServices(this IServiceCollection services,
IConfiguration configuration)
{
services.AddSingleton<IUnitOfWork, UnitOfWork>();
services.AddSingleton<IOrderRepository, OrderRepository>();
services.AddSingleton<ICustomerRepository, CustomerRepository>();
return services;
}
}
然后在启动类中如下:
services.AddCustomServices(Configuration);
好吧,错误信息非常有意义。 DI容器必须解析IUnitOfWork
的实例,它具有两个注入其ctor的依赖项。所以DI容器也必须解决这两个问题。
asp.net-core中没有内置功能,允许您使用模式匹配或类似的东西注册所有存储库。您可以逐个注册所有依赖项或使用第三方库。
使用Scrutor,您可以执行以下操作:
services.Scan(scan => scan
.FromAssemblyOf<OrderRepository>()
.AddClasses(classes => classes.AssignableTo<IRepository>())
.AsImplementedInterfaces()
.WithSingletonLifetime());
请注意,要使其工作,所有存储库必须实现IRepository
接口(可以为空)
结论:如果它只是少数依赖项,我可能会逐个注册它们,但是如果您打算稍后添加N个存储库 - 请使用第三方库。
IUnitOfWork
/ IOrderRepository
的IoC容器中没有注册服务。您通过使用AddSingleton方法注册这些服务来解决此问题。