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

时间:2018-11-27 09:16:37

标签: c# autofac generic-programming

在尝试使用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 :(得分:0)

错误消息表明IGenericService<EntCountry, Int32>未注册。

因为GenericService是抽象的,所以第一个解决方案是实现此类的实现

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>具有类约束(where TId : class),但TIdInt32的例外,它对于.net运行时无效。您应该删除类约束或更改TId的类型。