具有通用服务和存储库的 Autofac

Autofac with generic services and repository

我在尝试使用 Autofac 时遇到了架构设置的问题。

遇到的错误信息如下:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'xx.xx.xxxxxxx.HomeController' can be invoked with the available services and parameters: Cannot resolve parameter 'xx.Service.Common.IGenericService2[xx.Common.Models.EntCountry,System.Int32] countryService' of constructor 'Void .ctor(xx.Service.Common.IGenericService2[xx.Common.Models.EntCountry,System.Int32])'.

存储库接口和Class

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

服务接口和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();

感谢您的帮助。

此致。

错误信息表明IGenericService<EntCountry, Int32>没有注册。

因为 GenericService 是抽象的,第一个解决方案是实现这样的 class

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

然后Autofac会将FooService注册为IGenericService<Foo, Int32>

如果您不想实现而只使用 GenericService<T, TId>,则必须删除 abstract 修饰符并更改您在 Autofac[ 中注册类型的方式

不幸的是,在扫描程序集时没有简单的方法来注册开放泛型类型。在 Autofac Github 中有一个活跃的未解决问题:Support registering open generic types when scanning assemblies

最简单的解决方案是手动注册此类型

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

如果不可能,请查看 Github 问题,您可以使用一些解决方案。


所提供的代码还会有另一个问题。 IGenericService<T, TId> 有一个 class 约束(where TId : class),但在例外情况下 TId 是一个 Int32,它对 .net 运行时无效。您应该删除 class 约束或更改 TId 的类型。