通过约定和拦截进行注册会导致ResolutionFailedException [英] Registration by convention and interception causes ResolutionFailedException

查看:263
本文介绍了通过约定和拦截进行注册会导致ResolutionFailedException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简单场景

public interface IFoo
{
   int GetData();
}

public class Foo : IFoo
{
    [CacheResult]
    public int GetData() { .... }
}

public class MyController
{
    [Dependency]
    IFoo Foo {get; set;}
}

如果我手动注册接口,则解析MyController可以正常工作:

If I register the interface manually, resolving MyController works fine:

container.RegisterType<IFoo, Foo>(new ContainerControlledLifetimeManager(),
    new InterceptionBehavior<PolicyInjectionBehavior>(),
    new Interceptor<InterfaceInterceptor>());

var controller = container.Resolve<MyController>();

如果我尝试使用自动注册:

If I try to use auto-registration:

        container.RegisterTypes(
            AllClasses.FromLoadedAssemblies(),
            WithMappings.FromMatchingInterface,
            WithName.Default,
            WithLifetime.ContainerControlled,
            getInjectionMembers: t => new InjectionMember[]
            {
                new Interceptor<InterfaceInterceptor>(),
                new InterceptionBehavior<PolicyInjectionBehavior>(),
            });

var controller = container.Resolve<MyController>();

解析失败,出现ResolutionFailedException,因为传递的Type必须是接口.当然,如果我将其设为接口,则它将起作用,但前提是将其命名为Controller.如果我将其命名为MyController或SqlController或其他名称,则映射将失败,因为它无法解析该接口.

The resolve fails with a ResolutionFailedException because the Type passed must be an interface. Of course, if I make it an interface, it will work, but only if it is named Controller. If I call it, MyController or SqlController or whatever, then the mapping fails because it cannot resolve the interface.

我希望只进行程序集扫描,类似于Spring框架,但是我无法弄清楚.

I was hoping to just do an assembly scan, similar to what the Spring framework does, but I have not been able to figure it out.

我想念什么?还是在Unity中不可能?

What am I missing? Or is this not possible in Unity?

推荐答案

问题是AllClasses.FromLoadedAssemblies也在匹配并注册您的控制器.然后,当Unity尝试解析控制器(不是IFoo)时,它会发现 controller 未在接口中注册.

The problem is that AllClasses.FromLoadedAssemblies is matching and registering your controller as well. Then when Unity tries to resolve the controller (not IFoo), it finds that the controller is not registered with an interface.

这是一个帮助程序,可以将您的注册减少到只有具有匹配接口的那些类.

Here's a helper that will reduce your registrations to only those classes that have a matching interface.

public static class TypeFilters
{
    public static IEnumerable<Type> WithMatchingInterface(this IEnumerable<Type> types)
    {
        return types.Where(type => 
            type.GetTypeInfo().GetInterface("I" + type.Name) != null);
    }
}

然后您可以使用它来修改您的注册,就像这样...

and then you can use this to modify your registration like so...

AllClasses.FromLoadedAssemblies().WithMatchingInterface()

这篇关于通过约定和拦截进行注册会导致ResolutionFailedException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆