在Inet核心中注册IUnitOfWork作为服务

问题描述 投票:1回答:4

我将在我的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的代码

c# asp.net-core .net-core repository-pattern unit-of-work
4个回答
2
投票

这些错误意味着什么?

这些错误意味着您通过构造函数依赖注入使用服务,但您尚未将这些服务注册到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);

1
投票
  1. HomeController的构造函数采用IUnitOfWork,因此ASP.NET Core需要知道要给它的实例,这就是你在ConfigureServices中指定它的原因。但是,您的UnitOfWork类的构造函数需要一个IOrderRepository和一个ICustomerRepository,而ASP.NET Core需要知道要提供的那些实例,因此您还必须在ConfigureServices中指定它们。
  2. 我认为你最终得到的配置是正确的,但它没有解决你的下一个问题......
  3. 没有ASP.NET Core依赖注入问题的模式已经存在问题。 UnitOfWork的构造函数有两个不同的参数,每个参数对应一个存储库。如果您想拥有N个不同的存储库,那么该构造函数将不再有效。相反,也许您需要引入一个“存储库管理器”类,并将其注入构造函数中(也将它添加到ConfigureServices中)。然后,您需要设计UnitOfWork和RepositoryManager之间的关系,以允许UnitOfWork与任何特定的存储库一起使用。

1
投票

好吧,错误信息非常有意义。 DI容器必须解析IUnitOfWork的实例,它具有两个注入其ctor的依赖项。所以DI容器也必须解决这两个问题。

asp.net-core中没有内置功能,允许您使用模式匹配或类似的东西注册所有存储库。您可以逐个注册所有依赖项或使用第三方库。

使用Scrutor,您可以执行以下操作:

services.Scan(scan => scan
                    .FromAssemblyOf<OrderRepository>()
                    .AddClasses(classes => classes.AssignableTo<IRepository>())
                    .AsImplementedInterfaces()
                    .WithSingletonLifetime());

请注意,要使其工作,所有存储库必须实现IRepository接口(可以为空)

结论:如果它只是少数依赖项,我可能会逐个注册它们,但是如果您打算稍后添加N个存储库 - 请使用第三方库。


0
投票
  1. IUnitOfWork / IOrderRepository的IoC容器中没有注册服务。您通过使用AddSingleton方法注册这些服务来解决此问题。
  2. 不确定您的正确配置是什么意思,但是使用AddSingleton / AddTransient / AddScoped,您在IoC容器中注册了一些类作为服务。因此,当您注入某些内容(例如,进入HomeController)时,您将使用映射到某个具体实现的接口。
  3. 你必须以某种方式注册服务,这就是你之前提到的方法。如果您不注册它,它将无法解决,并且在尝试激活某些其他相关服务时您将获得异常。如果要在不明确说明的情况下注册某些服务,则必须扫描程序集并查找要注册的类型。
© www.soinside.com 2019 - 2024. All rights reserved.