如何将具体类注册到通用接口?

时间:2019-06-30 13:28:12

标签: c# generics dependency-injection castle-windsor aspnetboilerplate

我尝试注册基于泛型类的具体类,并且该泛型类基于泛型接口。问题是如何在Castle Windsor和ASP.NET Boilerplate中执行此操作,这样我就不需要很多代码来逐个注册它。

public interface IService<T> where T: class ...

public class Service<T, TE, TPrimary> : IService<T> where T: class ...

public class ConcreteService : Service<SomeType, SomeType2, string> ...
public class AnotherConcreteService : Service<AnotherSomeType, AnotherSomeType2, string> ...

使用这种结构,我想向IService<SomeType>注册实现该服务的类ConcreteService。温莎城堡怎么办?一对一的实现如下所示:

IocManager.IocContainer.Register(Component.For(typeof(IQueryService<SomeType>))
    .ImplementedBy(typeof(ConcreteService)).Named("ConcreteTest"));

IocManager.IocContainer.Register(Component.For(typeof(IQueryService<AnotherSomeType>))
    .ImplementedBy(typeof(AnotherConcreteService)).Named("AnotherConcreteTest"));

我想拥有的用途:

var test1 = IocContainer.Resolve<IQueryService<SomeType>(); // Here should be ConcreteService
var test2 = IocContainer.Resolve<IQueryService<AnotherSomeType>(); // Here should be AnotherConcreteService

使用逐行方法可以正常工作,但是如何基于IQueryService<>注册全部?

2 个答案:

答案 0 :(得分:2)

如果您的目标是在一个表达式中注册泛型IQueryService<T>的所有各种实现,那么您很可能会遇到类似这样的情况

container.Register(
   Classes.FromThisAssembly()
      .BasedOn(typeof(IQueryService<>))
      .WithServiceBase()
);

我强烈建议您花一些时间来探索the documentation的所有变体

答案 1 :(得分:1)

1。 IQueryService<SomeTypeDto>

  

Castle.MicroKernel.ComponentNotFoundException:没有支持服务AbpCompanyName.AbpProjectName.IGenerics.IQueryService`1的组件[[AbpCompanyName.AbpProjectName.SomeEntitiesDto.SomeTypeDto,AbpCompanyName.AbpProjectName.Application,版本= 1.0.0.0,Culture = neutral,找到PublicKeyToken = null]]

要将具体类注册到通用接口,请使用.WithService.Base()

为与RegisterAssemblyByConvention兼容 1 ,请配置唯一名称。

public override void Initialize()
{
    var thisAssembly = ...

    IocManager.RegisterAssemblyByConvention(thisAssembly);

    IocManager.IocContainer.Register(
        Classes.FromAssembly(thisAssembly)
            .BasedOn(typeof(IQueryService<>))
            .WithService.Base()
            .Configure(configurer => configurer.Named(Guid.NewGuid().ToString())) // Add this
    );

    // ...
}

1 如果您的具体类实现ASP.NET Boilerplate的ITransientDependency,则将使用默认名称在.WithService.Self()中为RegisterAssemblyByConvention注册该类。 / p>

2。 IRepository<SomeType>

  

Castle.MicroKernel.Handlers.HandlerException:无法创建组件'AbpCompanyName.AbpProjectName.SomeEntityService.SomeTypeService',因为它具有要满足的依赖性。

     

“ AbpCompanyName.AbpProjectName.SomeEntityService.SomeTypeService”正在等待以下依赖项:
  -未注册的服务'Abp.Domain.Repositories.IRepository`1 [[AbpCompanyName.AbpProjectName.SomeEntities.SomeType,AbpCompanyName.AbpProjectName.Core,版本= 1.0.0.0,区域性=中性,PublicKeyToken =空]]。 / p>

要使用ASP.NET样板库,请定义一个公共 DbSet。

public class AbpProjectNameDbContext : ...
{
    /* Define a DbSet for each entity of the application */

    // DbSet<SomeType> SomeEntities { get; set; }     // Remove this
    public DbSet<SomeType> SomeEntities { get; set; } // Add this

    // ...
}