无法解析一个从外部DLL加载控制器 [英] Unable to resolve a controller that was loaded from external dll

查看:231
本文介绍了无法解析一个从外部DLL加载控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我建立使用MVC4的Web API使用IoC容器在Web API(简单喷油器在这种情况下,但我不认为这个问题是有关的容器)应该揭露各种CRUD和查询操作。原因在我的情况下,使用国际奥委会是,我们是一个开发商店,我需要能够让客户建立自己的Web API控制器来揭露他们需要公开从我们的系统需要的数据。因此,我希望我的设计的方式,让我通过使所有的控制器内部测试自己的产品,无论是我们和我们的客户,外部和国际奥委会通过可装载的解决方案。

I am building a Web API using MVC4 Web API with an IoC container (Simple Injector in this case, but I don't think this problem is related to that container) that should expose a variety of CRUD and query operations. The reason for using IOC in my case is that we are a dev shop and I need to be able to let customers build their own web API controllers to expose the data they need to expose need from our system. Consequently, I was hoping to design my solution in a way that allowed me to dogfood my own product by making all the controllers, both ours and our customers', external and loadable through IOC.

该网站没有图书馆的任何引用,但库包含我想在网站上使用的控制器。类型被登记在容器和DependencyResolver设置为自定义依赖解析器。我有code查找DLL插件并加载控制器类型,但是当我尝试浏览到它会重新present它说,它无法找到它的路线。

The website does not have any reference to the library but the library contains controllers that I want to use in the website. The types are registered in the container and the DependencyResolver is set to the custom dependency resolver. I have the code finding the dll plugin and loading the controller type but when I try to navigate to the route that it would represent it says it can't find it.

即。如果我尝试浏览/ API / Test1Api我应该看到文本Hello World

i.e. if I try to navigate to /api/Test1Api I should see the text "hello world"

在这里,我的问题是,虽然我装我的控制器类型,我无法翻译成该网站说,一个路由那里。

My problem here is that although I have loaded my controller type, I am unable to translate that into a route that the website says is there.

我得到的错误

没有HTTP资源发现,请求URI匹配

No HTTP resource was found that matches the request URI

没有型,发现名为Test1Api。控制器匹配

No type was found that matches the controller named 'Test1Api'.

下面是我注册的容器

public static class SimpleInjectorInitializer
{
    /// <summary>Initialize the container and register it as MVC3 Dependency Resolver.</summary>
    public static void Initialize()
    {
        //// Did you know the container can diagnose your configuration? Go to: http://bit.ly/YE8OJj.

        // Create the IOC container.
        var container = new Container();

        InitializeContainer(container);

        container.RegisterMvcAttributeFilterProvider();
        // Verify the container configuration
        container.Verify();

        // Register the dependency resolver.
        GlobalConfiguration.Configuration.DependencyResolver =
                    new SimpleInjectorWebApiDependencyResolver(container);
    }

    private static void InitializeContainer(Container container)
    {
        var appPath = AppDomain.CurrentDomain.BaseDirectory;

        string[] files = Directory.GetFiles(appPath + "\\bin\\Plugins", "*.dll",
            SearchOption.AllDirectories);
        var assemblies = files.Select(Assembly.LoadFile);

        // register Web API controllers
        var apiControllerTypes =
            from assembly in assemblies
            where !assembly.IsDynamic
            from type in assembly.GetExportedTypes()
            where typeof(IHttpController).IsAssignableFrom(type)
            where !type.IsAbstract
            where !type.IsGenericTypeDefinition
            where type.Name.EndsWith("Controller", StringComparison.Ordinal)
            select type;

        // register MVC controllers
        var mvcControllerTypes =
            from assembly in assemblies
            where !assembly.IsDynamic
            from type in assembly.GetExportedTypes()
            where typeof(IController).IsAssignableFrom(type)
            where !type.IsAbstract
            where !type.IsGenericTypeDefinition
            where type.Name.EndsWith("Controller", StringComparison.Ordinal)
            select type;

        foreach (var controllerType in apiControllerTypes)
        {
            container.Register(controllerType);
        }

        foreach (var controllerType in mvcControllerTypes)
        {
            container.Register(controllerType);
        }
    }
}

任何帮助是AP preciated。

Any help is appreciated.

推荐答案

你的解决方案的一大警示。这是很重要的,以你的控制器注册到你的容器以及(这一建议适用于所有的DI框架,虽然一些框架默认强制你去注册的具体类型以及)。否则,你一定会得到了同样的问题<一咬href=\"http://stackoverflow.com/questions/15908019/simple-injector-unable-to-inject-dependencies-in-web-api-controllers\">this开发人员必须。

One big warning about your solution. It is quite crucial to register your controller into your container as well (this advice holds for all DI frameworks, although some frameworks by default force you to register concrete types as well). Otherwise you will certainly get bitten by the same problem as this developer had.

由于 IHttpControllerTypeResolver 利用了 IAssembliesResolver ,最简单的(和最安全的)解决方案是简单地问了 IHttpControllerTypeResolver 所有控件注册。你的 SimpleInjectorInitializer 在这种情况下会是这样的:

Since the IHttpControllerTypeResolver makes use of the IAssembliesResolver, the simplest (and safest) solution is to simply ask the IHttpControllerTypeResolver for all controls to register. Your SimpleInjectorInitializer in that case will look like this:

public static class SimpleInjectorInitializer
{
    public static void Initialize()
    {
        // Create the IOC container.
        var container = new Container();

        InitializeContainer(container);

        container.RegisterMvcAttributeFilterProvider();

        // Verify the container configuration
        container.Verify();

        // Register the dependency resolver.
        GlobalConfiguration.Configuration.DependencyResolver =
            new SimpleInjectorWebApiDependencyResolver(container);
    }

    private static void InitializeContainer(Container container)
    {
        GlobalConfiguration.Configuration.Services
            .Replace(typeof(IAssembliesResolver),
                new CustomAssembliesResolver());

        var services = GlobalConfiguration.Configuration.Services;
        var controllerTypes = services.GetHttpControllerTypeResolver()
            .GetControllerTypes(services.GetAssembliesResolver());

        // register Web API controllers (important!)
        foreach (var controllerType in controllerTypes)
        {
            container.Register(controllerType);
        }        
    }
}

另外请注意,你的 CustomAssembliesResolver 可制成相当容易:

public class CustomAssembliesResolver
    : DefaultAssembliesResolver
{
    private Assembly[] plugins = (
        from file in Directory.GetFiles(
            appPath + "\\bin\\Plugins", "*.dll",
            SearchOption.AllDirectories)
        let assembly = Assembly.LoadFile(file)
        select assembly)
        .ToArray();

    public override ICollection<Assembly> GetAssemblies()
    {
        var appPath =
            AppDomain.CurrentDomain.BaseDirectory;

        return base.GetAssemblies()
            .Union(this.plugins).ToArray();        
    }
}

这篇关于无法解析一个从外部DLL加载控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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