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.
Related
I understand this could be interpreted as an opinion question, but it is technical and a problem I am currently trying to solve.
In the Prism documentation, it is stated that modules should have loose coupling with no direct references, only going through shared interfaces. Like in the following picture:
My issue is, if only a few modules required an IOrdersRepository, the infrastructure is the wrong place for it, as this contains shared code for all of the modules. If I placed the interface in another module, then both modules will need to directly reference that one, breaking the loose coupling.
Should I simply create a library which contains this interface and doesn't follow the module pattern?
Thanks,
Luke
It should be definitely Infrastructure module. Markus' argument is absolutely right - you shouldn't create separate assembly for each shared set of interfaces. It's much more better to have Infrastructure module with a lot of interfaces istead of a lot of modules with some interfaces in each one. Imagine, that one time you will find, that 2 of yours "set of interfaces" should use some shared interface! What will you do? Add yet one assembly for that "super-shared" interfaces? Or combine those modules to one? It's wrong I think.
So - definitely Infrastructure module!
PS. Imagine, that .NET Framework has 1000s libraries - one for collections, anotherone for math functions etc....
UPDATE:
Actually, I use Infrastructure module mostly for interfaces and very basic DTOs. All shared code I move to another assembly (like YourApplication.UIControls, YourApplication.DAL etc.). I haven't enough reasons to do exactly this way, but this is my way to understand Prism's recomendations. Just IMHO.
UPDATE 2:
If you want to share your service so wide - I think it absolutely makes sence to have structure like:
YourApplication.Infrastructure - "very-shared" interfaces (like IPaymentService)
YourApplication.Modules.PaymentModule - "very-shared" implementation of your PaymentService
YourApplication.WPF.Infrastucture - infrastructure of your WPF application (in addition to YourApplication.Infrastructure
YourApplication.WPF.Modules.PaymentUI - some WPF specific UI for your YourApplication.Modules.PaymentModule
YourApplication.WebSite.Modules.PaymentUI - UI for web-site
And so on.. So, your modules will have almost always references to YourApplication.Infrastructure and YourApplication.TYPEOFAPP.Infrastructure, where TYPEOFAPP can be WPF, WebSite, WinService etc.. Or you can name it like YourApplication.Modules.PaymentUI.WPF..
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.
At our company we are developing an application that will consists of several modules. The architecture is pretty much defined but I have seconds thoughts about the presentationlayer and I would really like to hear your opinions. The architecture is as follows:
Foreach module we create several namespaces and those will be compiled in their own class library. So for our CRM module we create the following:
ProductName.CRM.ServiceLayer (holds the servicecontracts interfaces of CRM module)
ProductName.CRM.ServiceLayer.Implementation (implements the servicelayer interfaces of CRM module)
ProductName.CRM.BusinessLayer (holds the businesscomponents of CRM module)
ProductName.CRM.BusinessLayer.BusinessObjects (holds the businessObjects of CRM module)
ProductName.CRM.DataLayer (holds the DAO interfaces of CRM module)
ProductName.CRM.DataLayer.SqlServer (implements the datalayer interfaces of CRM module)
We create the same structure of class libraries for the modules Finance, HRM, Supply, etc:
ProductName.Finance....
ProductName.HRM....
etc.
I think you will get the idea for now :)
Also we thought about the "Crosscutting Concerns" and for that we create the following namespaces and class libraries
ProductName.Framework.ExceptionHandling
ProductName.Framework.Logging
ProductName.Framework.Security
etcetra...
So that is how our architecture is so far and at this moment I'm trying to find a proper way for setting up the PresentationLayer. For example, should I make a PresentationLayer-library foreach module (ProductName.CRM.PresentationLayer, ProductName.Finance.PresentationLayer, etc.). And make an overall ProductName.PresentationLayer-library who has references to all the other Module.PresentationLayer-libraries. This overall ProductName.PresentationLayer will then have the Login/MainForm functionality and the ability to start forms that are implemented in one of the modules PresentationLayer. It will be like an entry point of the application to other modules.
Or...
Should I make just one ProductName.Presentation-library that contains all forms for all modules. By doing that that I can easly navigate to other forms and don't have to worry about references between modules when they are going to use each others forms (sometimes they will do).
The first solutions sounds good to me. However, when forms from different modules wants to navigate to each other.This kind of functionality will be tough to implement because only one of the two can have the reference to the other.
I would really like to hear your opinions about this issue I'm dealing with and maybe someone could give me a proper solution or idea that I can use.
thanks in advance,
Cheers!
You can always create interfaces that forms implement if they need to exchange data. In fact, it's probably not a great idea to have lots of forms knowing about each other as that creates maintenance and enhancement problems in the long run.
By using interfaces and potentially some kind of Locator service, you can avoid hardwiring dependencies between forms - and then you are free to use either architectural model (1 big assembly vs. many smaller ones).
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
Let's say I have a common WCF service and console app project that do not change across client specific deployments. I have some interfaces in the common projects that are implemented by specific client code. The client code obviously changes from client to client. I'm thinking this would be an appropriate use for an IoC container. In my common service projects, I drop the client specific dll in the bin and wire up the dependencies via IoC. The only trick is that this has to be done dynamically as the common service projects can't have a direct reference on a specific client project. Not a big deal though.
Is this correct usage of an IoC container?
If I understood correctly your system, maybe you can benefit from taking a look at the Managed Extensibility Framework.
Dependency Injection (DI - what you call IoC) is a slightly different beast than supporting Add-Ins/PlugIns.
The purpose of DI is to manage dependencies and decrease coupling between different parts of a system. It can feel a bit like Add-Ins, but is slightly different because you usually just replace one implementation of an interface with another.
With Add-Ins, on the other hand, the purpose is to provide zero, one, or many implementations of the same service.
In both cases you may want to resolve the implementations at run-time based on configuration files, scanning a folder or similar, so there's a great degree of overlap.
What makes it even more complicated is that Add-Ins may have depedencies in their own right, and you may want to support that (moving into DI territory).
For the Add-In scenario, I will second Konamimam's suggestion: MEF sounds like it would fit your requirements.
Yes, this will work fine. You just need to make sure the client specific DLLs bring along their own registration. With StructureMap, it would be implemented as Registry classes in the client specific DLLs.