Регистрация службы IUnitOfWork As в .net core - PullRequest
0 голосов
/ 13 февраля 2019

Я собираюсь внедрить шаблон репозитория в мое основное приложение asp.net mvc, для этого я пробую свои силы в простом демонстрационном приложении, которое включает в себя репозиторий и концепцию Unit of Work. Мой первый репозиторий

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

IUnit Of Work

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();
        }
}

добавлюПозже будет написано больше кода, но по крайней мере он должен работать без каких-либо ошибок, но он дает мне ошибку

InvalidOperationException: невозможно разрешить службу для типа 'CoreTS.Repository.UnitOfWork.IUnitOfWork' при попыткеактивировать 'CoreTS.Controllers.HomeController'.

Кто-то предложил мне добавить IUnitOfWork в качестве службы в startup.cs в методе ConfigureService, как

services.AddSingleton<IUnitOfWork, UnitOfWork>();

и после добавления этой ошибки

InvalidOperationException: невозможно разрешить службу для типа 'CoreTS.Repository.Order.IOrderRepository' при попытке активировать 'CoreTS.Repository.UnitOfWork.UnitOfWork'.

Комузаставить его работать, я должен был также добавить два других хранилищав файле startup.cs также

services.AddSingleton<IOrderRepository, OrderRepository>();
services.AddSingleton<ICustomerRepository, CustomerRepository>();

Если в репозитории будет n номеров, то я должен добавить все из них в файле startup.cs (согласно этому коду), каково решение для этого.

Итак

1.] Что означают эти ошибки?

2.] Какая здесь будет правильная конфигурация?

3.] Как можно не добавлять n номер репозитория в качестве службы здесь?

Примечание. Как уже упоминалось, это просто для понимания последовательности шаблонов, я будудобавить код для Dapper или EF Core позже в этом

Ответы [ 4 ]

0 голосов
/ 13 февраля 2019
  1. Конструктор для HomeController принимает IUnitOfWork, поэтому ASP.NET Core необходимо знать, какой экземпляр ему предоставить, поэтому вы указываете его в ConfigureServices.Но конструктор вашего класса UnitOfWork принимает IOrderRepository и ICustomerRepository, и ASP.NET Core должен знать, какие экземпляры из них следует предоставить, поэтому вам также необходимо указать их в ConfigureServices.

  2. Я думаю, что конфигурация, в которой вы оказались, верна, но она не отвечает на ваш следующий вопрос ...

  3. Уже есть проблема сваш шаблон без проблем внедрения зависимостей ASP.NET Core.Ваш конструктор для UnitOfWork принимает 2 различных параметра, по одному для каждого хранилища.Если вы хотите иметь N разных репозиториев, этот конструктор больше не работает.Вместо этого, возможно, вам нужно ввести класс «менеджер хранилища» и просто внедрить его в конструктор (добавьте его также в ConfigureServices).Затем вам нужно разработать связь между UnitOfWork и RepositoryManager, которая позволит UnitOfWork работать с любым конкретным репозиторием.

0 голосов
/ 13 февраля 2019
  1. В контейнере IoC не зарегистрирована служба для IUnitOfWork / IOrderRepository.Вы решили эту проблему, зарегистрировав эти службы с помощью метода AddSingleton.

  2. Не уверен, что вы подразумеваете под правильной конфигурацией, но, используя AddSingleton / AddTransient / AddScoped, вы регистрируете некоторые классы как службы в контейнере IoC.,Поэтому, когда вы что-то внедряете (например, в свой HomeController), вы используете интерфейс, сопоставленный с какой-то конкретной реализацией.

  3. Вы должны каким-то образом зарегистрировать сервис, это то, чем вы являетесьделать с методами, упомянутыми ранее.Если вы не зарегистрируете его, он не будет решен, и вы получите исключения при попытке активировать некоторые другие зависимые службы.Если вы хотите зарегистрировать некоторые службы без явного выполнения, вам придется сканировать сборку и искать типы, которые вы хотите зарегистрировать.

0 голосов
/ 13 февраля 2019

Что означают эти ошибки?

Эта ошибка означает, что вы используете сервисы через конструктор Dependency Injection, но вы не зарегистрировали эти сервисы в DI resolver.

Какая здесь будет правильная конфигурация?

То, что вы сделали, - это правильный способ разрешения служб.

Какой способ не добавлять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);
0 голосов
/ 13 февраля 2019

Ну, сообщение об ошибке весьма значимо.Контейнер DI должен разрешить экземпляр IUnitOfWork, который имеет две зависимости, которые вставляются в его ctor.Таким образом, DI-контейнер также должен разрешать эти два.

В asp.net-core нет встроенной функциональности, которая позволяла бы регистрировать все ваши репозитории, используя сопоставление с образцом или что-то в этом роде.Вы можете зарегистрировать все зависимости одну за другой или использовать сторонние библиотеки.

С Scrutor вы можете сделать что-то вроде этого:

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

Обратите внимание, что для его работывсе репозитории должны реализовывать интерфейс IRepository (который может быть пустым)

Вывод: если есть только несколько зависимостей, я бы, вероятно, зарегистрировал их по одной, однако, если вы планируете добавить N репозиториев позже - используйте стороннюю версиюЛИЭС.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...