【问题标题】:Simple Injector with asp.net mvc 4, load controller from another assembly带有 asp.net mvc 4 的简单注入器,从另一个程序集加载控制器
【发布时间】:2013-01-04 09:35:44
【问题描述】:

我正在开发一个 asp.net mvc 4 站点,使用 Simple Injector 作为 Ioc 工具。这将是一个可插拔的架构。一些控制器和视图在另一个程序集中(另一个 mvc4 应用程序,Plugin.Web.dll)。并且从主应用中,我知道 Plugin.Web.dll 的路径,加载插件。

container.RegisterMvcControllers(Assembly.GetExecutingAssembly());

container.RegisterMvcAttributeFilterProvider();

container.Options.AllowOverridingRegistrations = true;

var appPath = AppDomain.CurrentDomain.BaseDirectory;

string[] files = Directory.GetFiles(appPath + "\\Plugins", "*",
    SearchOption.AllDirectories);

foreach (var fileName in files)
{
    Console.WriteLine(fileName);

    var assembly = Assembly.LoadFrom(fileName);

    container.RegisterMvcControllers(assembly);

    var controllerTypes =
        from type in assembly.GetExportedTypes()
        where type.Name.EndsWith("Controller",
            StringComparison.Ordinal)
        where typeof(IController).IsAssignableFrom(type)
        where !type.IsAbstract
        select type;

    // Instead of verify:
    foreach (var type in controllerTypes)
    {
        container.GetInstance(type);
    }
}            

container.Options.AllowOverridingRegistrations = false;       

container.Verify();

DependencyResolver.SetResolver(
    new SimpleInjectorDependencyResolver(container));

它没有给出任何错误。

但是当我点击这个点击时,在视图中:

@Html.ActionLink("plugin page","PluginPage","Plugin")

它给出'找不到资源。,http 404'

提前致谢

【问题讨论】:

    标签: .net asp.net-mvc dependency-injection asp.net-mvc-4 simple-injector


    【解决方案1】:

    恐怕你需要做更多的研究,因为你的问题目前有点模糊,但这里有一些建议:

    检查System.Web.Compilation.BuildManager.GetReferencedAssemblies() 是否返回您的插件程序集。 MVC DefaultControllerFactory 在从该方法返回的所有程序集中搜索 Controller 类型。最好的方法是将插件文件夹放在 /bin 目录中。如果我没记错的话GetReferencedAssemblies() 也会在 /bin 的子目录中查找。如果必须更动态地加载插件,您可能需要编写自定义控制器工厂。

    还可以查看this article,因为它描述了如何强制 BuildManager 了解您的插件程序集。

    您的配置似乎过于复杂。以下配置也应该可以解决问题:

    container.RegisterMvcControllers(Assembly.GetExecutingAssembly());
    
    container.RegisterMvcAttributeFilterProvider();
    
    var appPath = AppDomain.CurrentDomain.BaseDirectory;
    
    string[] files = Directory.GetFiles(appPath + "\\bin\\Plugins", "*",
        SearchOption.AllDirectories);
    
    container.RegisterMvcControllers(
        from fileName in files
        select Assembly.LoadFrom(fileName)
    );    
    
    container.Verify();
    

    您可以查询容器的配置以查看其中包含的内容。例如,这将查询所有注册的控制器:

    var registeredControllerTypes = (
        from registration in container.GetCurrentRegistrations()
        where typeof(IController).IsAssignableFrom(registration.ServiceType)
        select registration.ServiceType)
        .ToArray();
    

    【讨论】:

    • 当我将插件 dll 放在 bin 目录中时,它可以工作。
    • 还可以查看this article,因为它描述了如何强制 BuildManager 了解您的插件程序集。
    • 请尽量避免使用AllowOverridingRegistrations = true。允许容器覆盖现有注册可以很容易地错过配置错误。如果您不需要它,请不要启用它。如果您需要它,请查看配置,如果您可以更改配置以使其不需要使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多