Autofac с общими службами и хранилищем - PullRequest
0 голосов
/ 27 ноября 2018

Я столкнулся с проблемой с установленной архитектурой при попытке использовать Autofac.

Обнаружено сообщение об ошибке:

Ни один из конструкторов не найден с 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' для типа 'xx.xx.xxxxxxx.HomeController'может быть вызван с помощью доступных служб и параметров: Невозможно разрешить параметр 'xx.Service.Common.IGenericService 2[xx.Common.Models.EntCountry,System.Int32] countryService' of constructor 'Void .ctor(xx.Service.Common.IGenericService 2 [xx.Common.Models.EntCountry, System.Int32])'.

Интерфейс хранилища и класс

 public interface IGenericRepository<T,TId> 
        where T: class , IEntity<TId>
    {...}

 public abstract class GenericRepository<T, TId> : IGenericRepository<T, TId>  
        where T : class, IEntity<TId>
        where TId : class {}

Сервисный интерфейс и класс

 public interface IGenericService<T,TId> where T : class , IEntity<TId> 
    {...}



public abstract class GenericService<T, TId> : IGenericService<T, TId>  
        where T : class, IEntity<TId> 
        where TId : class{...}

Код контроллера

   public class HomeController : Controller
    {

    private readonly IGenericService<EntCountry, int> _countryService;

    public HomeController(IGenericService<EntCountry, int> countryService)
    {
        _countryService = countryService;
    }

    // GET: Home
    public ActionResult Index()
    {

        var countries = _countryService.GetAll();

        return View();
    }
}

Моя конфигурация Autofac для сервисов и репозитория следующая:

builder.RegisterAssemblyTypes(Assembly.Load("XX.Data"))
                   .Where(t => t.Name.EndsWith("Repository"))
                   .AsImplementedInterfaces()
                   .AsSelf()
     .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies)
                   .InstancePerLifetimeScope();





 builder.RegisterAssemblyTypes(Assembly.Load("XX.Service"))
                   .Where(t => t.Name.EndsWith("Service"))
                   .AsImplementedInterfaces()
                   .AsSelf()
                   .PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies)
                   .InstancePerLifetimeScope();

Я пытался использовать метод Register Generic, но я все еще получал ту же ошибку

builder.RegisterGeneric(typeof(GenericRepository<,>))
                .As(typeof(IGenericRepository<,>))
                .AsSelf()
                .InstancePerDependency();

Спасибо за вашу помощь.

С наилучшими пожеланиями.

1 Ответ

0 голосов
/ 27 ноября 2018

Сообщение об ошибке указывает, что IGenericService<EntCountry, Int32> не зарегистрировано.

Поскольку GenericService является абстрактным, первое решение будет иметь реализацию такого класса

public class FooService : GenericService<Foo, Int32> 
{ }

Тогда Autofac зарегистрирует FooService как IGenericService<Foo, Int32>

Если вы не хотите иметь реализацию, а используете только GenericService<T, TId>, вам придется удалить модификатор abstract и изменитькак вы регистрируете свой тип в Autofac .

К сожалению, при сканировании сборок нет простого способа регистрации открытого универсального типа.В Autofac Github существует активная открытая проблема: Поддержка регистрации открытых универсальных типов при сканировании сборок

Самое простое решение - зарегистрировать этот тип вручную

builder.RegisterGeneric(typeof(GenericService<,>))
       .AsImplementedInterfaces();

Если это невозможно, взгляните на проблему с Github, есть решение, с которым вы можете поиграть.


Также будет другая проблема с предоставленным кодом.У IGenericService<T, TId> есть ограничение класса (where TId : class), но за исключением TId - это Int32, которое недопустимо для среды выполнения .net.Вы должны удалить ограничение класса или изменить тип TId.

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