如何注册通用存储库的依赖?

时间:2018-04-10 21:04:06

标签: asp.net repository inversion-of-control castle-windsor aspnetboilerplate

我有以下存储库基础:

public class FakeRepositoryBase<TEntity, TPrimaryKey> : AbpRepositoryBase<TEntity, TPrimaryKey>
    where TEntity : class, IEntity<TPrimaryKey>
{...}

继承自第一个:

public class FakeRepositoryBase<TEntity> : FakeRepositoryBase<TEntity, int>, IRepository<TEntity>
    where TEntity : class, IEntity<int>
{...}

模块注册:

[DependsOn(typeof(AbpKernelModule))]
public class DERCFakeDALModule: AbpModule
{
    public override void Initialize()
    {
        IocManager.RegisterAssemblyByConvention(Assembly.GetExecutingAssembly());
    }
}

然后我宣布AppService:

class DocumentAppService : ApplicationService, IDocumentAppService
{
    private readonly IRepository<Document> _documentRepository;
    private readonly IObjectMapper _objectMapper;

    public DocumentAppService(
        IRepository<Document> documentRepository,
        IObjectMapper objectMapper)
    {
        _documentRepository = documentRepository;
        _objectMapper = objectMapper;
    }

    // AppService methods
}

并将所有依赖项添加到我的WebModule中:

[DependsOn(
        typeof(AbpWebMvcModule),
        typeof(DERCApplicationModule), 
        typeof(DERCWebApiModule),
        typeof(DERCFakeDALModule))]
public class DERCWebModule : AbpModule

调用任何API方法后,都会出现错误:

{
  "message": "An error has occurred.",
  "exceptionMessage": "ComponentActivator: could not proxy Abp.WebApi.Controllers.Dynamic.DynamicApiController`1[[DERC.ApplicationServices.Interfaces.IDocumentAppService, DERC.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]",
  "exceptionType": "Castle.MicroKernel.ComponentActivator.ComponentActivatorException",
  "stackTrace": "   в Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext context, ConstructorCandidate constructor, Object[] arguments)\r\n   в Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context)\r\n   в Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context)\r\n   в Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden)\r\n   в Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally)\r\n   в Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy)\r\n   в Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden)\r\n   в Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired)\r\n   в Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context)\r\n   в Castle.MicroKernel.DefaultKernel.ResolveComponent(IHandler handler, Type service, IDictionary additionalArguments, IReleasePolicy policy)\r\n   в Castle.MicroKernel.DefaultKernel.Castle.MicroKernel.IKernelInternal.Resolve(Type service, IDictionary arguments, IReleasePolicy policy)\r\n   в Castle.MicroKernel.DefaultKernel.Resolve(Type service, IDictionary arguments)\r\n   в Castle.Windsor.WindsorContainer.Resolve(Type service)\r\n   в Abp.Dependency.IocManager.Resolve(Type type)\r\n   в Abp.Dependency.IocResolverExtensions.ResolveAsDisposable[T](IIocResolver iocResolver, Type type)\r\n   в Abp.WebApi.Controllers.AbpApiControllerActivator.Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)\r\n   в System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage request)\r\n   в System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()",
  "innerException": {
    "message": "An error has occurred.",
    "exceptionMessage": "Can't create component 'DERC.ApplicationServices.DocumentAppService' as it has dependencies to be satisfied.\r\n\r\n'DERC.ApplicationServices.DocumentAppService' is waiting for the following dependencies:\r\n- Service 'Abp.Domain.Repositories.IRepository`1[[DERC.Entities.Document, DERC.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' which was not registered.\r\n",
    "exceptionType": "Castle.MicroKernel.Handlers.HandlerException",
    "stackTrace": "   в Castle.MicroKernel.Handlers.DefaultHandler.AssertNotWaitingForDependency()\r\n   в Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden)\r\n   в Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired)\r\n   в Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context)\r\n   в Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveFromKernelByType(CreationContext context, ComponentModel model, DependencyModel dependency)\r\n   в Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveFromKernel(CreationContext context, ComponentModel model, DependencyModel dependency)\r\n   в Castle.MicroKernel.Resolvers.DefaultDependencyResolver.ResolveCore(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)\r\n   в Castle.MicroKernel.Resolvers.DefaultDependencyResolver.Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency)\r\n   в Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context)\r\n   в Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.Instantiate(CreationContext context)\r\n   в Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.InternalCreate(CreationContext context)\r\n   в Castle.MicroKernel.ComponentActivator.AbstractComponentActivator.Create(CreationContext context, Burden burden)\r\n   в Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.CreateInstance(CreationContext context, Boolean trackedExternally)\r\n   в Castle.MicroKernel.Lifestyle.AbstractLifestyleManager.Resolve(CreationContext context, IReleasePolicy releasePolicy)\r\n   в Castle.MicroKernel.Handlers.DefaultHandler.ResolveCore(CreationContext context, Boolean requiresDecommission, Boolean instanceRequired, Burden& burden)\r\n   в Castle.MicroKernel.Handlers.DefaultHandler.Resolve(CreationContext context, Boolean instanceRequired)\r\n   в Castle.MicroKernel.Handlers.AbstractHandler.Resolve(CreationContext context)\r\n   в Castle.Core.InterceptorReference.Castle.MicroKernel.IReference<Castle.DynamicProxy.IInterceptor>.Resolve(IKernel kernel, CreationContext context)\r\n   в Castle.Windsor.Proxy.AbstractProxyFactory.ObtainInterceptors(IKernel kernel, ComponentModel model, CreationContext context)\r\n   в Castle.Windsor.Proxy.DefaultProxyFactory.Create(IKernel kernel, Object target, ComponentModel model, CreationContext context, Object[] constructorArguments)\r\n   в Castle.MicroKernel.ComponentActivator.DefaultComponentActivator.CreateInstance(CreationContext context, ConstructorCandidate constructor, Object[] arguments)"
  }
}

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

检查基本会议注册时,您可以看到:

        //Transient
        context.IocManager.IocContainer.Register(
            Classes.FromAssembly(context.Assembly)
                .IncludeNonPublicTypes()
                .BasedOn<ITransientDependency>()
                .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                .WithService.Self()
                .WithService.DefaultInterfaces()
                .LifestyleTransient()
            );

        //Singleton
        context.IocManager.IocContainer.Register(
            Classes.FromAssembly(context.Assembly)
                .IncludeNonPublicTypes()
                .BasedOn<ISingletonDependency>()
                .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                .WithService.Self()
                .WithService.DefaultInterfaces()
                .LifestyleSingleton()
            );

        //Windsor Interceptors
        context.IocManager.IocContainer.Register(
            Classes.FromAssembly(context.Assembly)
                .IncludeNonPublicTypes()
                .BasedOn<IInterceptor>()
                .If(type => !type.GetTypeInfo().IsGenericTypeDefinition)
                .WithService.Self()
                .LifestyleTransient()
            );

这意味着首先必须使用ITransientDependencyISingletonDependency接口来标记依赖关系,以便能够按约定注册它们。然后无论如何都会排除泛型类型,因此您必须通过标准方法注册它们:

IocManager.IocContainer.Register(Component.For(typeof(ITest<,>)).ImplementedBy(typeof(Test<,>)));