This project is read-only.

MVC3 integration

Apr 23, 2012 at 12:35 PM

I check the following page: http://simpleinjector.codeplex.com/SourceControl/changeset/view/89207#2060429 Is it the correct code for the MVC3 integration?

If so, here are some suggestions

Make a proper class libary

Makes it easier to find and read the code (to know how the integration works) and to come with patches (hint: codeplex supports git now ;)).

Scoping

I couldn't find how you handle scoping (creating instances in the beginning of the request and disposing them in the end). Check for instance the Unity.MVC3 project here at codeplex for a sample.

Registering controllers

I usually use several class libraries in my applications. Can you make a method which registers all controllers in an assembly?

Something like (extension method):

 

container.RegisterControllers(typeof(MyController).Assembly);

 

Controller factory

No need for a controller factory if you are using the DependencyResolver.

(you might want to write that in the wiki)

Modules

Got nothing to do with MVC3 but containers in general.

I tend to create an interface like:

public interface IContainerModule
{
    void Register(IMyFavoriteContainer container);
}

Which I make several implementations of (one per plugin / application feature). I then scan all assemblies after classes the implement that interface, instantiate them and invoke them using the container. In that way I have full control over the registration process and doesn't have to expose the container anywhere else.

The registrations area easier to find since they are located in the same place as the services that they register.

Can you add support for that in your container so that I can invoke something like:

container.RegisterModules(Assembly.GetExecutingAssembly());

Thanks ;)

Apr 28, 2012 at 4:04 PM

Hi Jonas,

Thank you very much for your feedback. It is very helpful. The file in source control you are pointing at is indeed the file that is used for the MVC Integration NuGet package.

Make a proper class library

The integration package currently adds this file to the MVC project and the package does indeed not contain a class library. My idea was to remove any 'magic' so users could easily see what the registration does (and that it really doesn't do that much). But you are right about applying patches. An NuGet package update will not override any existing file, which effectively disallows any updates. Making it a class library will also allow adding extension methods such as RegisterPerWebRequest. In other words, good point.

GIT

I must say I'm  pleased with how TFS works, so for me there is no appealing reason to switch to another source code system. Please enlighten me what the benefits would be to switch to GIT.

Scoping

There is a RegisterPerWebRequest code snippet in the documentation that allows you to do per web request (what comes close to doing lifetime scoping). My idea is to add this extension method to the MVC integration library.

The documentation also contains a section about how to extend the Simple Injector with lifetime scoping, something that is not supported out of the box. I have though about adding it to the SimpleInjector.Extensions.dll, but decided not to for two reasons.

First of all I thought that too little Simple Injector users would want to use it anyway, and it would therefore clutter the API (however, I currently see more and more users doing advanced stuff with the Simple Injector that are hardly impossible to achieve with some other containers). Let me know what you think about this.

The other reason not to add it, is because there is a quirk in the current implementation as shown in the documentation. For certain configurations it is possible that the container disposes an instance that should be disposed (such as a singleton instance). For that reason the documentation notes that a call to "container.Verify();" must be added, but even this isn't full-proof. This quirk comes from the fact that Simple Injector has no native support for lifetime scoping and is added using the existing extension points. I believe the quirk can be fixed, even without adding native support for this, but I have to think about this.

Registering controllers

When you look closely at the SimpleInjectorMVC3Extensions class you referenced, you'll see there is a RegisterControllers method with the exact signature as what you propose :-)

Controller factory

For MVC3 there is indeed no need for registering an IControllerFactory, since Controllers will be created using the DependencyResolver.Current. For this reason, the MVC3 integration package only registers an IDependencyResolver, but the Wiki page does indeed not explain this. I also think it is good to update the wiki to explain this.

Modules

I know most containers have a modules like feature, and I have considered this, but IMO this isn't really useful. I answered a SO question about this a few months back, where I explain this. Besides, the RegisterModules method as you propose is so easy to write yourself, that this by itself justifies leaving it out of the library (keeping the API small and simple is one of the most important design goals for the Simple Injector). Here is a extension method that exactly does what you like:

public static void RegisterModules(this Container container,
    params Assembly[] assemblies)
{
    assemblies = assemblies ?? AppDomain.Current.GetAssemblies();

    var modules =
        from assembly in assemblies
        from type in assembly.GetExportedTypes()
        where typeof(IContainerModule).IsAssignableFrom(type)
        select (IContainerModule)Activator.CreateInstance(type);

    foreach (var module in modules)
        module.Register(container);
}

Please let me know what you think of all this.

Cheers

Apr 30, 2012 at 8:43 PM
Edited Apr 30, 2012 at 8:45 PM

Git

Git is not about the benefits for you, but for collaboration. It's a lot easier to participate in a project when using git (compared to TFS or Subversion) and it's much faster since the entire repo is local. I can make my own clone of your code and use it on all my machines (I got three computers that I code on) and I don't have to commit my changes to the original (your) repos until I'm ready. However, I can still commit my changes to my clone (and therefore get version control).

Scoping

Great. Add it to the new Mvc3 project. You can add a dependency to System.Web.WebPages to automaticall hook a HttpModule into ASP.NET and therefore be able to dispose everything directly from the package. 

http://msdn.microsoft.com/en-us/library/gg548426(v=vs.99).aspx

Modules

It's all about convenience. If I should create it I either have to educate my users on how to do it (I'm a team leader for two dev departments as my current assignment) or put the module features in a class library somewhere.

However, if you provide it I get an "official" version which has been tested and improved by several users.

Other items

Nothing more to add, sounds great.

May 20, 2012 at 10:33 PM

Part of the discussed issues have been fixed with the latest release.

The SimpleInjector.MVC3 Integration NuGet package now installs an assembly containing the proper extension methods.

There are two new packages that enable scoping.

  • The Simple Injector Lifetime Scoping Extensions NuGet package allows defining an explicit scope (by calling container.BeginLifetimeScope) for services registered with one of the RegisterLifetimeScope extension methods. Instances will be automatically disposed when the lifetime scope ends. The problems with Lifetime Scoping that existed in the extension methods on the wiki have been fixed in the official package. For more information, read here.
  • The Simple Injector ASP.NET Integration NuGet package allows registering instances per web request (this package is included with the MVC3 NuGet package). Instances will be automatically disposed when the web request ends. Within the context of HTTP web requests, the use of this lifestyle is advised over the Lifetime Scope lifestyle. For more information, read here.

If you have any feedback on this, or anything else, please let me know.

May 26, 2012 at 10:04 PM
Edited Oct 6, 2012 at 1:45 PM

A new NuGet package has been released that implements support for modules; or 'packages' as Simple Injector calls them.

A package is created by implementing the IPackage interface:

 

public class BusinessLayerPackage : IPackage
{
     public void RegisterServices(Container container)
     {
         container.Register<IUserRepository, DbUserRepository>();
         container.Register<ICustomerRepository, DbCustomerRepository>();
     }
 }

All packages can be applied by calling the following extension method:

 

 container.RegisterPackages();

This will load all packages that are defined in assemblies currently loaded in the current AppDomain. Alternatively, you can specify a set of assemblies from where packages must be loaded. For instance:

 

container.RegisterPackages(
    BuildManager.GetReferencedAssemblies().Cast<Assembly>());
Marked as answer by dot_NET_Junkie on 11/3/2013 at 11:53 PM