如何将具体类注册到泛型接口?

3
我尝试注册基于泛型类的具体类,而这个泛型类是基于泛型接口的。问题在于如何在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> ...

有了这样的结构,我希望将实现该服务的ConcreteService类注册到IService<SomeType>中。在Castle Windsor中,我该如何做呢?一一实现的方式如下:

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个回答

2
如果你的目标是在一个表达式中注册所有通用的 IQueryService<T> 实现,那么你可能需要像这样做:

"如果您的目标是在一个表达式中注册所有通用的IQueryService<T>实现,那么您最有可能需要以下代码:"
container.Register(
   Classes.FromThisAssembly()
      .BasedOn(typeof(IQueryService<>))
      .WithServiceBase()
);

我强烈建议花些时间阅读文档,其中探讨了所有的变体。将原始答案翻译为“最初的回答”。

我强烈建议您花些时间阅读文档,以确保您对IoC容器的API和使用模式感到舒适,并帮助您避免常见问题。特别是请参阅https://github.com/castleproject/Windsor/blob/master/docs/faq.md、https://github.com/castleproject/Windsor/blob/master/docs/three-calls-pattern.md和https://github.com/castleproject/Windsor/blob/master/docs/ioc.md。 - Krzysztof Kozmic
1
@CrazyBaran 哪些依赖项? - aaron
@CrazyBaran 请在GitHub上创建一个可复制的项目,派生自 aspnetboilerplate/module-zero-core-template - aaron
@aaron 你可以在这里找到可复制的项目 https://github.com/CrazyBaran/module-zero-core-template - CrazyBaran
@aaron 我重构了项目,请检查一下。原来在控制器中的构造函数里是 IQuery<SomeEntityDto>,现在改成了 IQuery<SomeTypeDto>。它由应用层的 SomeTypeService 实现。接口在 IGenerics 中。 - CrazyBaran

2

1. IQueryService<SomeTypeDto>

Castle.MicroKernel.ComponentNotFoundException: 找不到支持AbpCompanyName.AbpProjectName.IGenerics.IQueryService`1[[AbpCompanyName.AbpProjectName.SomeEntitiesDto.SomeTypeDto, AbpCompanyName.AbpProjectName.Application, Version=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,那么默认名称将用于在RegisterAssemblyByConvention中为.WithService.Self()注册该类。

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, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'未注册。

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

    // ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接