4

I'm developing an asp.net mvc 4 site, using Simple Injector as a Ioc tool. It would be a pluggable architecture. Some controllers and views are in another assembly (another mvc4 application, Plugin.Web.dll). And from the main application, I know the path of Plugin.Web.dll, loading the plugin.

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));

It gives no errors.

But when I click this click, in view:

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

It gives 'The resource cannot be found., http 404'

thanks in advance

1 Answer 1

5

I'm afraid you'll have to do some more research, since your question is a bit vague at the moment, but here are some pointers:

Check if System.Web.Compilation.BuildManager.GetReferencedAssemblies() returns your plugin assemblies. The MVC DefaultControllerFactory searches for Controller types in all assemblies returned from that method. Best is to place your plugin folder inside the /bin directory. If I'm not mistaken GetReferencedAssemblies() also looks in sub directories of /bin. You'll probably need to write a custom controller factory if plugins must be loaded more dynamically.

Also take a look at this article, as it describes how to force the BuildManager to know about your plugin assemblies.

Your configuration seems overly complex. The following configuration should do the trick as well:

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();

You can query the container's configuration to look what it contains. For instance, this will query all registered controllers:

var registeredControllerTypes = (
    from registration in container.GetCurrentRegistrations()
    where typeof(IController).IsAssignableFrom(registration.ServiceType)
    select registration.ServiceType)
    .ToArray();
Sign up to request clarification or add additional context in comments.

3 Comments

When I place the plugin dll, inside the bin directory it works.
Also take a look at this article, as it describes how to force the BuildManager to know about your plugin assemblies.
Please try to prevent the use of AllowOverridingRegistrations = true whenever possible. Allowing the container to override existing registrations can make it easy to miss configuration errors. Don't enable it if you don't need it. And if you need it, please take a look at the configuration if you can change the configuration in such way the its usage is not required.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.