DryIOC WebAPI后备控制器

时间:2016-03-23 13:27:22

标签: c# asp.net-web-api dryioc

我使用DryIOC.WebAPI来解析我的APIControllers。

WebAPI配置因此:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        // Configure Web API to use only bearer token authentication.
        config.SuppressDefaultHostAuthentication();
        config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));


        config.EnableCors();
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        Startup.IocContainer.WithWebApi(config);
        Startup.IocContainer.RegisterWebApiControllers(config);
    }
}

它工作得很好,直到我忘记在IOC容器中创建映射。在这种情况下,Dependency解析器无法使用DryIOC创建APIController的实例。

当发生这种情况时,它会回退到默认的WebAPI解析器,然后使用" No默认构造函数"错误。

这对我来说是不受欢迎的行为。如果DryIOC解析失败,我希望停止那里 - 没有回退到默认实现,并且没有关于没有默认构造函数的不准确消息。我想知道DryIOC无法解决的类型,所以我可以解决它。

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

根据Microsoft文档:

Dependency Injection in ASP.NET Web API 2

  

如果 GetService 方法无法解析类型,则应返回   空值。如果 GetServices 方法无法解析类型,则应该   返回一个空的集合对象。

     

不要为未知类型抛出异常

     

此接口的实现应委托给底层   依赖注入容器为注册服务提供   请求的类型。当没有注册的服务时   请求类型,ASP.NET MVC框架期望实现   此接口从 GetService 返回 null 并返回空   来自 GetServices 的集合。

     

当Web API首先创建控制器实例时   调用IDependencyResolver.GetService,传入控制器类型。   您可以使用此扩展性挂钩来创建控制器,   解决任何依赖关系。如果 GetService 返回null,则Web API会显示   对于控制器类上的无参数构造函数。

您可以自己覆盖默认解析器

public static class ResolverHelper {
    public static void OverrideResolver(this HttpConfiguration httpConfiguration) {
        var innerResolver = httpConfiguration.DependencyResolver;
        var resolver = new MyDryIocDependencyResolver(innerResolver);
        httpConfiguration.DependencyResolver = resolver;
    }
}

并且在你的自定义解析器中失败了你想要的。

来自MyDryIocDependencyResolver

的代码段
public class MyDryIocDependencyResolver : IDependencyResolver { 
    IDependencyResolver innerResolver;

    public MyCustomDependencyResolver(IDependencyResolver innerResolver) {
        this.innerResolver = innerResolver;
    }

    public IDependencyScope BeginScope() {
        return this;
    }

    public object GetService(Type serviceType) {
        try {
            return innerResolver.Getservice(serviceType);
        } catch (Exception ex) {
            //TODO: Log resolution error
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType) {
        try {
            return innerResolver.GetServices(serviceType);
        } catch (Exception ex) {
           //TODO: Log resolution error
           return new List<object>();
        }
    }

    public void Dispose() {
      // NO-OP 
    }
}

在您的注册中,您可以覆盖它

//...other code
Startup.IocContainer.WithWebApi(config);
Startup.IocContainer.RegisterWebApiControllers(config);
config.OverrideResolver();
//...other code

这样,如果/当DryIocDependencyResolver无法解析服务类型时,您仍然会知道未解决的内容,捕获它,并返回建议指南所指示的默认值。两全其美。

希望有所帮助

答案 1 :(得分:1)

使用IContainer.VerifyResolutions方法检查具有所有可能信息的Controller分辨率问题的另一种方法是使用{/ 1}}方法。

例如:

var container = new Container().WithWebApi(config);
var errors = container.VerifyResolutions();
Debug.Assert(errors.Length == 0);

wiki中的更多细节。

注意: 控制器的唯一捕获,当前 DryIoc.WebApi 使用具体控制器类型及其所有实现类型作为服务类型来注册控制器实现。因此,对于一个未解决的class MyController: ApiController {}方法,VerifyResolutions将返回3个相同的错误:

  • 一个MyController
  • 一个ApiController
  • IHttpController
  • 的一个

您可以按errors对结果验证Factory.FactoryID进行分组,以获得更紧凑的输出。