BT

ASP.NET MVC, Dependency Injection, and MEF 2

by Jonathan Allen on Dec 05, 2011 |

For most types of applications dependency injection frameworks don’t make whole lot of sense. It is usually more than sufficient to manually wire up all of the dependencies during startup and call it a day. But for ASP.NET MVC, there isn’t really one startup. Each dependency may be scoped to the server, the user session, the controller, or to an individual request. With so many competing lifecycles a DI framework quickly moves from needless distraction to an essential organizational tool.

Seeing this as an important use case, MEF 2 will include functionality specific to dealing with MVC dependencies. All this will be done using a convention-based approach; no extra configuration files will be needed.

When using MEF 2 a new folder called Parts is needed. This is where one stores classes that are going to be needed by controllers to handle things such as data access, logging, and communicating with other sites and web services. To indicate what parts are needed for a given controller, simply list them in the controller’s constructor. The same is done when a given part needs other parts.

By default parts have the lifetime of a single request and no more than one of each part will be created no matter how many controllers or other parts need it. Once the request is done, Dispose is called on any parts that need it. If a part’s lifetime should instead be that of the application, then the ApplicationShared attribute may be applied to it. Advanced registration options are available, but attribute tagging should handle most use cases.

Parts from other assemblies may be included by using the CompositionProvider.AddPartsAssembly function in Application_Start. It should be noted that all parts must include the identifier “Parts” in their namespace. The BCL team writes,

Having to use a Parts namespace for all parts may seem a little excessive, but it is a good reminder that not every class should be a part. Parts are the ‘coarse-grained’ chunks that make up an application. Assemblies that add non-trivial functionality will almost always have a large number of additional supporting classes that the parts in the assembly use, but that are not parts themselves.

Parts that represent model binders must be tagged with the ModelBinderExport attribute and the type of model it applies to.

Action filters may also participate in composition. While they cannot be created by the MEF composition provider, they can have properties filled in by MEF. To do this tag the MEF-managed property with the Import attribute.

A sample of ASP.NET MVC with MEF 2 is available on CodePlex.

Hello stranger!

You need to Register an InfoQ account or to post comments. But there's so much more behind being registered.

Get the most out of the InfoQ experience.

Tell us what you think

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Really? by Mark N

"For most types of applications dependency injection frameworks don’t make whole lot of sense". I would say that for most types it DOES make sense. I am sure for a few it does not.

"It is usually more than sufficient to manually wire up all of the dependencies during startup and call it a day." What do you think DI does? DI is not just injecting objects. I does include configuration.

Re: Really? by Sergej Koščejev

I would say that for most types it DOES make sense. I am sure for a few it does not.

"Most" is subjective. I'd say that for most types it DOESN'T make sense. I am sure for a few it does (such as "web apps" - one type out of many).

What do you think DI does? DI is not just injecting objects. I does include configuration.

DI involves configuring the container and injecting stuff into the container before you can get the objects back from it. Injecting them manually saves you a dependency on a third-party library and is more straightforward.

Re: Really? by Mike Wang

It sounds like you're just into developing really overcomplicated systems. Not to worry, you've got a lot of company.

"For most types of applications dependency injection frameworks don’t make whole lot of sense". I would say that for most types it DOES make sense. I am sure for a few it does not.

"It is usually more than sufficient to manually wire up all of the dependencies during startup and call it a day." What do you think DI does? DI is not just injecting objects. I does include configuration.

Re: Really? by Jonathan Allen

Support for configuration is usually handled with the ConfigurationManager (ConfigurationSettings prior to .NET 2.0).

It often takes less code to explicitly pass in configuration values to a constructor during startup then it takes to properly configure and initialize a DI framework. And since the only time a DI framework should be running is app startup, a reduced LOC count is really the only reason to even consider using one.

Again, I make an exception for ASP.NET MVC where “startup” is really done on a per-request basis and each controller may need slightly different resources.

Re: Really? by Mark N

I do DI/IoC for desktop, web, batch, integration .... It makes sense for all of them.

Injection can be done via xml, code, declaratively, etc. You don't have to configure the container (Look at Spring 3.0). Injecting them manually means: You probably have things tightly coupled, you are rolling (and maintaining) your own "container" or just maybe we are saying the same thing :).

Re: Really? by Mark N

Nope. It simplifies things. People who take a simplistic view of software development think it is "overly complicated". It is sometimes? Yes.

You will have dependencies in most systems. It is easier to use an existing tool than go at it yourself. Just choose wisely.

Re: Really? by Mark N

"It often takes less code to explicitly pass in configuration values to a constructor during startup then it takes to properly configure and initialize a DI framework". Maybe it does. But it takes more code to set things up so you can test.

How is
if(testing)
new SomeClass(new DummyService())
else
new SomeClass(new SomeService());

easier than

@Autowired
class SomeClass
...
@Service
class SomeService....


Additionally IoC/DI points are good places to do AOP, etc. If you are doing it yourself, then you will be doing a lot more and more potential for mistakes.

Re: Really? by David Clarke

PM> install-package Munq.MVC3

Seriously,
to properly configure and initialize a DI framework
is trivial. Munq happens to be a lightweight DI framework I like and am familiar with but there are a number of other more feature-rich DI frameworks. Really the point is there are many good reasons to use a DI framework and suggesting reducing LOC
is really the only reason to even consider using one
is ridiculous. Did you perhaps mean reducing LOC is the only reason *NOT* to consider using one? And reducing LOC is really only a good reason for doing one thing, removing cruft/duplication.

Re: Really? by Sergej Koščejev

Really the point is there are many good reasons to use a DI framework


I'm curious, can you then name at least two reasons to use a DI framework (container) in a non-Web application, in preference to do-it-yourself DI?

Re: Really? by David Clarke

Only 2?
1. Ease of unit testing/mocking
2. Encourages decoupling, i.e. Program to an interface, not an implementation

Web or non-web isn't really relevant to the discussion. In my experience the judicial application of a DI framework informs good application design and ultimately results in a better quality product. If you're interested, have a look at Mark Seeman's Dependency Injection in .NET

Re: Really? by Sergej Koščejev

Only 2?
1. Ease of unit testing/mocking
2. Encourages decoupling, i.e. Program to an interface, not an implementation

Please re-read my question carefully, I think you missed the "in preference to do-it-yourself DI" part. The two advantages you mentioned I can easily get just by using dependency injection without a container.

Re: Really? by David Clarke

Fair enough, 2 reasons why container-based DI is preferable to DIY DI:
1. A container can provide autowiring of dependencies
2. A container can provide lifetime management of objects
As the size/complexity of an application grows, a DIY DI solution will naturally tend to become a DIY DI container. Sure you can write container-type features yourself and sometimes it does make sense to reinvent the wheel. My previous comment still stands, using a container has streamlined and improved my designs, reduced impedance when testing, and ultimately allowed me to deliver a better product. YMMV

Re: Really? by Duraid Duraid

Ok now list 2 reasons why DIY DI is preferable to container-based DI and then you can decide.

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

Allowed html: a,b,br,blockquote,i,li,pre,u,ul,p

Email me replies to any of my messages in this thread

13 Discuss

Educational Content

General Feedback
Bugs
Advertising
Editorial
InfoQ.com and all content copyright © 2006-2013 C4Media Inc. InfoQ.com hosted at Contegix, the best ISP we've ever worked with.
Privacy policy
BT