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

How to register Concrete Class to Generic Interface?

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

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> class 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<>注册所有内容?

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

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

我强烈建议花一些时间在 the documentation 上探索所有变体

1。 IQueryService<SomeTypeDto>

Castle.MicroKernel.ComponentNotFoundException: No component for supporting the service AbpCompanyName.AbpProjectName.IGenerics.IQueryService`1[[AbpCompanyName.AbpProjectName.SomeEntitiesDto.SomeTypeDto, AbpCompanyName.AbpProjectName.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] was found

要向通用接口注册具体的 classes,请使用 .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 如果您的具体 class 实现了 ASP.NET 样板的 ITransientDependency,则默认名称用于注册 class .WithService.Self() 里面 RegisterAssemblyByConvention.

2。 IRepository<SomeType>

Castle.MicroKernel.Handlers.HandlerException: Can't create component 'AbpCompanyName.AbpProjectName.SomeEntityService.SomeTypeService' as it has dependencies to be satisfied.

'AbpCompanyName.AbpProjectName.SomeEntityService.SomeTypeService' is waiting for the following dependencies:
- Service 'Abp.Domain.Repositories.IRepository`1[[AbpCompanyName.AbpProjectName.SomeEntities.SomeType, AbpCompanyName.AbpProjectName.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' which was not registered.

要使用 ASP.NET 样板存储库,请定义一个 public 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

    // ...
}