MEF: Where should I put the CompositionContainer? - c#

I have been using the Windsor IoC Container for my web-based application, to resolve the data access layer implementation the application should use.
The web application's UI will consist of pages, and each page consists of small units called portlets. (Their concept is somewhat similar to widgets.) These so-called portlets are basically web controls and can be configured in runtime for every page invidually.
The application will ship with some of these built-in, but I would like to enable extending it easily.
I figured out that this mechanism is exactly what MEF is built for. So I decided to implement the system in such a way that it discovers portlets using MEF. Then, I realized that it can also do what I currently use Windsor for, so I decided to ditch Windsor in favor of MEF.
Obviously, I will have to use the DirectoryCatalog, which scans for the .dlls in the app's bin folder and returns everything I need.
I read some tutorials, examples, and all questions regarding MEF in StackOverflow, as well. I figured that the easiest way to use MEF is through the PartInitializer which Glenn Block mentioned in his tutorials, but I realized that it is not in MEF. Actually, it is in the code I downloaded from CodePlex, but in a separate assembly, and only in source, not in binary form. (Does this mean that it isn't a part of MEF? Or what's the point in putting it to a separate project?)
Then, I realized that it is for Silverlight, so it doesn't really help me.
(Or should I just compile that against .NET 3.5, or include it in my project, and I'm good to go?)
So now I have a problem which is the following: where should I put the CompositionContainer in my application?
There is another thing I would like to consider: should I use only one CompositionContainer in the lifetime of the app, or I'm better off creating a container for every time when I need it?

Good questions.
In general in terms of questions about where to put the container, I recommend the following posts: http://blogs.msdn.com/nblumhardt/archive/tags/Container+Managed+Application+Design/default.aspx
In of MEF on the web, web-based apps are a bit tricker because of the request / response nature and scalability concerns. For web you would likely want to have a hierarchy of containers, one root one for the application which is shared, as well as child contianers per-request. The child containers should live and die with the request in order to conserve resources. The shared container contains services that are shared by all callers.
You might check out these articles for more insight into how to do this:
http://blogs.msdn.com/hammett/archive/2009/04/23/mef-and-asp-net-mvc-sample.aspx
http://blogs.msdn.com/hammett/archive/2009/07/15/mef-and-asp-net-mvc-sample-updated.aspx
http://mef.codeplex.com/wikipage?title=Parts%20Lifetime&referringTitle=Guide
As far as PartInitializer, I would avoid using something like it unless you have to. ASP.NET provides sufficient hooks in the pipeline through HTTP Handlers, modules and such to let automatically compose on creation.
The only place i would see using PI on the web would be possibly within a custom user control. PI ships as part of Silverlight 4 and is not available in the box for .NET 4.0. I have created a usable version for .NET 4.0 which you can find here: http://cid-f8b2fd72406fb218.skydrive.live.com/self.aspx/blog/Composition.Initialization.Desktop.zip
HTH
Glenn

Related

Using IoC in an application that use a library that doesn't use IoC

I am currently using a library (SuperWebSocket) which is a websocket server library that use a bootstrap which know which instances to load from a configuration file. I have implemented a bootstrap class for this (however the instances arent loaded using IoC). Also the commands from this server are loaded from assemblies reflection. I wanted to use this server in conjonction with my DAL and service layer which use IoC. My main problem is that i can't find a way to put this Console Application (Server) and cooperation with the lib in an IoC scenario without having to end up using the ServiceLocator.
Normally the kernel (Ninject) should be located at the composition root (Look like to be the best practice from many around..) which is rather not possible to do in this case or at least i didn't found how so that why i am here. Also the commands are loaded from assemblies reflection. I could implement a CommandLoader however this is still a problem cause they all inherit from the same interface (Multibinding maybe?). I could make custom interface for each of them but i still can't find a way to load them automatically. Even if i found a way to load them, i still have to be able to get service from attributes which is not easy to do.
Any suggestions ?
If I understand your question correctly then the library is the entry point for all work done. In this situation it depends on the framework what to do. Here are some things you can do the first things are the preferred ones:
Inspect the library and find some way to hook into the framework to intercept the creation of your objects.
Call kernel.Inject(this) after an object is created by the library. Have a look at the Ninject.Web extension. There we added some base classes e.g. NinjectWebPage for WebPage. This new base class calls kernel.Inject after creation. New web pages can now be derived from that base class and use property injection to get dependencies.
Use the ServiceLocator pattern in the objects created by the libray. But just at this level. Anything deeper should use dependency injection.

Plugin system with MVC3, Razor and C#

I'm fairly decent with MVC3 and enjoy creating my sites with it, however, I am yet to think up and implement a decent method of a "plugin" system.
Basically, I aim to have a generic "blog-type" CMS which I can distribute across my sites, but with the option to have certain things as plugins.
For example:
Generic build:
User area
Basic blog/news editing
Plugins: (May be needed for one or two sites, but not all)
Chatroom plugin
Stats
and so on...
Currently I would just make it all and disable things through a config file, however it would be nice if i could just drop a folder into my FTP and have an MVC page which automatically picks it up!
I assume I would have to start with scanning the directory "/plugins" and picking up a "plugin.config" (Or similar) file which would contain the basic details.
But how would I get my main system to pick these things up and actually use them?!
You may be able to do this using MVC Areas, here are some links about them:
ASP.NET MVC 2 Areas
ASP.NET MVC Areas: Are they important to a large application?
https://stackoverflow.com/questions/462458/asp-net-mvc-areas-are-they-important-to-a-large-application
Try assembly scanning with StructureMap dependency injection.
Read this great tutorial: ASP.NET MVC2 Plugin Architecture Tutorial
It help me create a plugin architecture with MVC3.
Areas solve the problem for you providing you have everything in the original project/assembly. You could write your plugin system to allow the plugins to register their own areas, or alternatively you could register some new view search paths in a custom Razor view engine.
I chose the latter for a recent OS project I wrote called Spruce, which uses a whole plugin architecture you might find useful as a reference.
You can scan all the assemblies in the bin directory on startup to check for plugins, via reflection. You usually check for types that implement an interface or inherit from a class, and use these along side an IoC container such as TinyIoc, NInject, StructureMap or Unity. I'd recommend TinyIoC which is used by NancyFX.

MEF Best practices: Where in the application I create container and where to call Compose()?

I have decided to use MEF for a plugin pattern I have and found MEF easy to pick up and not intrusive at all. I looked at samples and found them very easy to work with.
However, as soon as started implementing, I started struggling with the composition. Let's say I have a Class which has [ImportMany] on one of its properties. All examples I have seen, they create the Container in the class which has imports (let's call it composable) and basically the class composes itself. That might be OK for an example but surely putting knowledge of how the plugin gets populated is too much for the composable to know.
I can happily create a singleton container and access it in my composable but again the composable has to explicitly call Compose() on itself and I am not happy with that either as it is like a dependency injection scenario where the class pro-actively calls the Resolve() on the container. So I do not want to use it for just Service Location.
To make the matters worse I am also using Windsor Castle for DI and I am not sure how MEF and Windsor must work together.
I have really looked around and have not been able to find any guidance and sample on how to do MEF right. Now it might be that I have not looked around or I do not know MEF well enough (which is true) but will value your views from the experience of actually using it in the real world.
Do not do that. I used MEF for my last project and I wish to not do that.
There's a good idea behind it (composition) and I was do that manually for years. I was happy for the first official version in .NET 4.0 but there a re still a lot of design problems.
Unfortunately it's part of Microsoft policy to leave testing and bug finding to end users and feedback the hard-earned bugs and suggestions.
MEF is good if you use the way the example says. As soon as you need a little change you will find there's not enough documentation and nobody will answer you. Here are some of my never resolved issues with MEF and you can find my questions in codeplex.com which never had been answered by the developer team:
1) How to pass parameters to part's constructors (they may say use ExportFactory which is shipped in codeplex version but I wasted a long time on this, and I can say there's not an acceptable solution for that)
2) How to set configurations for parts ? (I ended-up passing configurations to parts through a method which is a bad idea, but the best available)
3) MEF is very slow because it use reflection under the hood. For my case loading 1,000 parts takes 60 seconds.
4) Debugging is awesome. You get unclear messages. You will end-up downloading the full source from codeplex and search your exceptions inside the code.
After all I think if you have other choices, let MEF gets mature and use the next version.
I just shared my own experience.
The recommended pattern is for you to create the container once in your hosting code, and only access it from there to get the "root" part. You would call container.GetExport<Root>() if it's OK for MEF to create the part for you, otherwise you would call container.SatisfyImports(root).
The root part should import the things it needs, and the parts supplying those exports should import what they need, and so on. MEF will create the whole graph and none of the parts need to call into the container directly. The samples often have very few different parts, so it isn't always obvious that the container creation and composition should only occur once, even in more complex applications.
There are situations where you may have object that need their imports satisfied, but can't be created by MEF. An example of this is WPF/Silverlight UI objects that are created by the Xaml parser. In this case you might resort to a service which allows these objects to request that their imports be satisfied.
I don't have much advice for how to use MEF and another DI container in the same application. If there isn't much interaction between the parts of the system composed with MEF and Windsor it might work without much trouble. If you need components from one container to be injected with components from the other container, it won't be as simple. One way would be to have a service that a component would have to call to resolve its dependencies from the other container. The other possibility would be to have the containers themselves linked. You can do this in theory with MEF by writing an ExportProvider that accesses the Windsor container. In practice it would require a very deep level of knowledge about MEF, and it might not be possible to get it to work exactly how you'd like.

Is MEF an all-or-nothing affair?

I've had a few questions about MEF recently, but here's the big one -- is it really all-or-nothing, as it appears to be?
My basic application structure is simply an app, several shared libraries that are intended to be singletons, and several different plugins (which may implement different interfaces). The app loads the plugins, and both the app and all plugins need to access the shared libraries.
My first go at MEF was fairly successful, although I made some stupid mistakes along the way because I was trying so many different things, I just got confused at times. But in the end, last night I got my smallish test app running with MEF, some shared libraries, and one plugin.
Now I'm moving onto the target app, which I already described. And it's the multiple plugins part that has be a bit worried.
My existing application already supports multiple plugins with different interfaces by using Reflection. I need to be able to uniquely identify each plugin so that the user can select one and get the expected behavior exposed by that plugin. The problem is that I don't know how to do this yet... but that's the topic of a different question.
Ideally, I'd be able to take my existing plugin loader and use it as-is, while relying on MEF to do the shared library resolution. The problem is, I can't seem to get MEF to load them (i.e. I get a CompositionException when calling ComposeParts()) unless I also use MEF to load the plugin. And if I do this, well... then I need to know how to keep track of them as they get loaded so the user can select one from a list of plugins.
What have your experiences been with trying to mix and match these approaches?
MEF is designed to let you easily load plugin assemblies. If you have control over the plugins (by which I mean that you can add MEF export attributes) then there is no need to keep your own plugin loader which uses reflection. MEF does all that for you.
That being said, "mixing and matching" MEF with other technologies is certainly possible. It sounds like your problem is that if you use your own plugin loader, you don't add those plug-ins to the MEF container. As a result, you get a CompositionException for parts which try to import the selected plug-in.
To add a plugin that you loaded with your own code to the MEF container, you can use the ComposeExportedValue like this:
container.ComposeExportedValue<IPlugin>(selectedPlugin);
edit: I see what you mean now by "all or nothing". Your problem is that in order to be able to import parts with MEF, you also need to construct the object with MEF. This problem then cascades to the object which normally created that object, etc. all the way to the application root.
To avoid this "all or nothing" effect, you can compromise by exposing the MEF container as a global variable (i.e. static field). That way, classes can access the MEF container and pull exports from it, e.g. by calling Program.Container.GetExportedValue<MyDependency>() in the constructor.
edit2: If you have an object that was not constructed by MEF, then there are two ways to add it to the container.
The first is to call container.ComposeExportedValue<IMyContractType>(myObject);.
The second is to return the object in a property getter, and then mark the property itself with an [Export(typeof(SomeType))] attribute.

Simple tips to reduce coupling

I have a large .NET web application. The system has projects for different intentions (e.g. CMS, Forum, eCommerce), and I have noticed a (naive) pattern of calling on another project's class. For example, the ecommerce module needs functionality to generate a file on the fly for products, and I call and reference a method in the CMS to do this, because file handling is really a job for the CMS.
Obviously (and I know why), this is bad design and a case of high coupling.
I know a few ways to handle high coupling, like restructuring the project (although I don't really think this is a robust solution), but what else can I do to reduce high coupling? Any simple tips? Also, it would be good to know why/how they reduce coupling. I use .NET 3.5 and Sql Server 2005 so things like JMS (which I keep coming across in my search for tips on this design issue), are not applicable.
Thanks
BTW,
One of the reasons I ask this is that I have read the previous questions similar to this but usually if a question that has been asked before is asked again, different tips can be learnt as different people reply to the post.
I know of dependency injection/IOC, but I am interested in the small things that can be done to reduce coupling.
How could I choose between using a static class, or an interface-derived class, or the IOC approach when deciding on how to reduce coupling? Also, I could develop a web service which could call a static class - mixing up the approaches in my solution.
The interesting thing is that in my application, I don't want it to be disjointed. So I just have a forum, ecommerce system, and any other module required, but everything has to gel into one site so each module (which is represented as a dedicated project in my Visual Studio solution) needs to know about every other module and work with it. So for example, I might have a module which handles user profiles (working with ASP.NET membership, roles, etc), but this will work with the forum module as a user on the forum will be a registered user on the site (one login throughout), and his or her profile will be coming from the user profile module. This is as opposed to seperate profiles as seen on other sites I've come across).
You should expose web services in those projects who will be needed by other projects. This is kind of the base level idea behind SOA. So, I would just create web services and consume them, which will decouple you quite a bit from how you have it now. Hope this helps.
I'd consider starting by doing an "extract interface" refactoring on the tightly coupled pieces. For example, if using the CMS as a backing store, create an interface that can store things, then create a mediator or adapter class that knows about the CMS, but isolate the logic that knows about the storage mechanism details to just that class.
Then, for testing, you can easily substitute an in-memory store or local-filesystem store that doesn't depend on the CMS being up.
Consider using techniques like dependency injection (See StructureMap, Spring.Net, NInject) to simplify instantiation if a simple factory doesn't give you the flexibility you need.
It sounds like you have a layering problem. Your assemblies should have a single dependency cycle - from least stable to most stable. That allows you to version sensibly. Generally, that cycle would be something like UI (least stable) -> Domain Core (stable) -> Data Access (most stable). You can throw in a Utilities or some infrastructre assemblies along the way, but again - they should be considered more stable than the assemblies dependent on them.
I'd guess your App.ECommerce and App.Cms assemblies are more siblings than layers - so you would not want those to depend on each other, but that doesn't mean you can't reuse functionality. For your particular scenario, you need to push the needed functionality down to a Core or Utilities assembly that both ECommerce and Cms can depend on. If it's a specific implementation that ECommerce provides, then you can push an interface or abstract base class to the Core - and have a higher layer (perhaps IoC container) wire up the concrete Cms.FileCreator class to the ECommerce.IFileCreator dependency.
Get proper abstractions in place as described by others (interfaces, etc). Program against abstractions, not concretions.
Design your classes with Dependency Injection in mind as you have described.
Use an Inversion of Control Container as the mortar between the bricks.
Unity from the Patterns & Practices team complements the Enterprise Library.
Scott Hanselman has a nice List of .NET Inversion of Control Containers.
Well, I don't know anything about .NET, but how about refactoring common code into a separate, underlaying project/layer? Loads of stuff in a web app can be done generically to suit both a CMS, a forum and eCommerce, writing to a file is a perfect example.
Another approach could be to see the forum and eCommerce as modules in a CMS, which would also make sense. Then they could safely use specified API:s of the CMS.

Categories