Как автоматически добавлять зависимости в netcore2 - PullRequest
0 голосов
/ 21 апреля 2019

У меня есть несколько пар интерфейсов, и я реализую их так

ICategoryService -> CategoryService
ICategoryTypeService -> CategoryTypeService
IOrderService -> OrderService
ILoggingService -> LoggingService

Все классы и интерфейсы находятся в Data.dll, и я повторяю это следующим образом.

foreach (var type in serviceAssembly.GetTypes())
{
    if (type.Name.Contains("Repository") && !type.IsInterface && !type.IsGenericType)
    {
        Type interfaceImplement = type.GetInterfaces().SingleOrDefault(t => t.IsGenericType == false);

        if (interfaceImplement != null)
        {
            System.Diagnostics.Debug.WriteLine($"{type.Name} is inherited by {interfaceImplement.Name}");
            services.AddTransient(interfaceImplement, type);
        }
    }
}

и я получаюэта ошибка

InvalidOperationException: невозможно разрешить службу для типа «VietWebSite.Service.ILoggingService» при попытке активировать «VietWebSite.Web.Areas.WebApi.Administrator.ValuesController».

но это работает, если я изменю свой код так:

services.AddTransient<ILoggingService, LoggingService>();
services.AddTransient<ICategoryService, CategoryService>();
services.AddTransient<ICategoryTypeService, CategoryTypeService>();
services.AddTransient<IOrderService, OrderService>();

Пожалуйста, помогите.

Спасибо

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

Вот рабочая демонстрация:

  1. Создание Data библиотеки с классом и интерфейсом:

    public interface ICategoryService
    {
        string Output();
    }
    public class CategoryService : ICategoryService
    {
        public string Output()
        {
            return "CategoryService.Output";
        }
    }
    public interface ILoggingService
    {
        string Output();
    }
    public class LoggingService : ILoggingService
    {
        public string Output()
        {
            return "LoggingService.Output";
        }
    }
    
  2. Добавить Data библиотечную ссылку на основной проект asp.net

  3. Настроить Startup.cs как

    var serviceAssembly = Assembly.GetAssembly(typeof(CategoryService));
    foreach (var type in serviceAssembly.GetTypes())
    {
        if (type.Name.Contains("Service") && !type.IsInterface && !type.IsGenericType)
        {
            Type interfaceImplement = type.GetInterfaces().SingleOrDefault(t => t.IsGenericType == false);
    
            if (interfaceImplement != null)
            {
                System.Diagnostics.Debug.WriteLine($"{type.Name} is inherited by {interfaceImplement.Name}");
                services.AddTransient(interfaceImplement, type);
            }
        }
    }
    
  4. Вариант использования:

    public class HomeController : Controller
    {
        private readonly ILoggingService _loggingService;
        public HomeController(ILoggingService loggingService)
        {
            _loggingService = loggingService;
        }
        public IActionResult Index()
        {
            var result = _loggingService.Output();
            return View();
        }        
    }
    

Обновление :

Ваша проблема вызвана тем, что AppDomain.CurrentDomain.GetAssemblies() будет возвращать только загруженные сборки, попробуйте код ниже:

//Load Assemblies
//Get All assemblies.
var refAssembyNames = Assembly.GetExecutingAssembly()
    .GetReferencedAssemblies();
//Load referenced assemblies
foreach (var asslembyNames in refAssembyNames)
{
    Assembly.Load(asslembyNames);
}
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
var myAssemblies = assemblies.Where(assem => assem.GetName().Name.Contains("VietWebSite.Data") || assem.GetName().Name.Equals("VietWebSite.Service"));
0 голосов
/ 21 апреля 2019

Как вы это сделали, это правильный ручной способ сделать это.Я не знаю автоматического способа внедрения зависимостей, о котором я знаю, но есть доступные пакеты, такие как AutoFac https://autofac.org/.

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