如何将具体 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
// ...
}
我尝试注册基于泛型 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
// ...
}