Appropriate Situation for Using IoC Container? - c#

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.

Related

I have Domain Driven Design Concerns on my VS project

I am dealing with some architectural design concerns that is needed to be sorted out. My current architecture can be seen below. Each box is a project in visual studio, and they together forms solution.
My Core application is coded in WestCore.AppCore Context, and I have another project group called CSBINS (which includes system web service integrations) CSBINS is an merchant product that is why I found it better to seperate it to another project and only depend it with most commonly used interfaces from WestCore.AppCore.
Right now WestCore.Api does not have any logic in it. All the application logic is handled inside AppCore and AppCore.Csbins
The Problem is I sometimes have need to use WestCore.AppCore.Csbins services inside WestCore.AppCore which causes cross referencing issue.
the best approach right now that I think is to add Endpoint Services into WestCore.Api and move cross platform logic to Endpoint Services.
However I would like to get suggestions and design concerns about going further on this since I am very sure that there would be many design choices.
I am also considering to move common AppCore Interfaces and Classes to WestCore.AppCore.Common so that I wont need to reference whole WestCore.AppCore project to WestCore.AppCore.Csbins.
Why are you using services inside other services - this is probably a bad thing and needs refactoring.
Those CORE projects look like are application services projects, it might help calling them 'WestCore.ApplicationServices', Core implies it belongs at the domain level.
It sounds like you need to impliment an anti corruption layer to integrate with the 3rd party vendor rather than creating a whole new 'domain' context. This should be as straightforward as degining an interface in your domain layer (personally I use the *Gateway suffix to identifiy interfaces that interact with external systems)
Not knowing anything about your domain I would probably start with something that looks like this: (I've assumed the csbins is some sort of payment or accounting gateway)
Also, I would strongly recommend avoiding "Common" and "Shared" libraries at the domain level, you shouldn't need them. Your interfaces and classes are DOMAIN objects and belong in your DOMAIN library. The Application Services should be using domain models directly and having implementation of domain interfaces supplied via Dependency Injection. Hopefully your Domain Models are fleshed out enough that your application service classes are just orchestration wrappers.

Should I separate IoC binding seperation by project

I am new at domain driven design architecture. My project solution is like this:
Presentation(Web)
ApplicationLayer
QueryLayer
QueryHandlerLayer
DataLayer
I read from articles theese separations is doing to isolate jobs.
Presentation project references ApplicationLayer
But does not reference QueryLayer,QueryHandlerLayer and DataLayer.
But I am using IoC container and bind types to interface.
container.Bind(data interfaces).To(data classes);
container.Bind(query interfaces).To(query classes);
I can do this on PresentationLayer. But now all projects will be add reference to presentation layer.
Is this an issue about architecture? Or May I separated IoC container binding for all layers?
Using DI is about composing applications. An application might have multiple layers, but they are still part of the same application and must be composed together.
The appropriate place to compose an application is in the composition root, which should be as close to the entry point of the application as possible.
There are basically 3 common recommendations for composing applications with multiple layers, and all of them are perfectly acceptable.
Don't separate the layers into physical assemblies.
Compose the application in the presentation layer, and reference all other layers from the presentation layer.
Create a separate composition layer that references all of the other layers.
For the 3rd option, you should keep in mind that the composition layer is supposed to drive, not be driven by, the rest of the application.
See this answer for the reasoning behind this referencing and why it is important that you do reference every library from the composition root to avoid tight coupling. Or, as mentioned, you could use late binding to compose your application without referencing the assemblies directly, provided your deployment script copies over the DLLs.
I think the biggest thing I have learnt in recent usage is that at the fundamental level, DI is about Injecting Dependancies. That's a pretty redundant description, so let me elaborate:
DI starts with design. Everything should have what it needs provided to it via a constructor, or factory of some sort. This is where Interfaces are your best friend. Once you have done this, most of the work is done. Assuming some of the projects are shared, you have now delegated out all of the work to whoever is using it. This is probably old news, however.
Next, if you are in control of the container, consider creating a default module, which in the case of Ninject is a, NinjectModule. Create one of these for each application layer. This will form the "instructions" so to speak, for the container at the highest level of your program to put all the pieces together.
This can all be loaded by reflection trickery of which there is plenty of information around, like this.
Then it is as simple as loading all of these binding "instruction manuals" into the composition root (usually in the application) and you're good to go.

Can I register all IoC container components in single layer, or each layer where used?

I'm using the Unity IoC framework and have a Bootstrapper.cs class in my host MVC layer to register all components. However in my architecture I have a 'services' layer below the MVC layer, that too uses DI and there are repository interfaces injected into it (repository interfaces are not used in the MVC layer - it has the services layer Interface injected into its Controllers).
So my question is the following: can I still register the repository interface to it's concrete type in the MVC/UI layer for the entire app, or do I add another reference to Unity and create another Bootstrapper.cs class in my 'services' layer to define Interface types for that that specific layer uses?
Even if the answer is I can register the Interface in the UI layer, I'd still like to know the common practice too. The thing I don't like about registering that type in the MVC/UI layer is I would have to add a reference to the Repository layer just to make the registration, even know it is not used in that layer. It's used in the services layer.
Thanks!
Each application should have its own Composition Root, the place where you configure the application (see this answer for details).
It depends on the context, but generally speaking, if you split your container configuration among the layers you are going to make decisions about the configuration of your layers too close to the layers and you'are likely to lose the general view.
For example, in one of your business logic layers you'are registering a service:
container.RegisterType<ISercice1, MyImplementation1>(new PerThreadLifetime())
But when using that layer in a web application you could decide that a PerSession or PerRequest lifetime would be better lifetimes. This decisions should be in only one place and not spread through the layers.
I turn your question on its head.
If you add a reference to Unity in your class libraries, you would have added dependencies to the framework you are using. That is quite the opposite of what you are trying to achieve.
The only adaptation your classes should need is to support constructors or using public properties - on interfaces. That's it!
So your application entry point should do all the 'bootstrapping'.
Note that a entry point could be different applications, as well as different test projects. They could have different configurations and mocking scenarios.
If your bootstrap.cs gets large, you could split it up into smaller parts for readability reasons. But I reject the idea of classes having any knowledge about the fact that they are being bootstrapped/moqed/injected and by what.
Consider re-use. Your current libraries is using Unity. They may be used in a project using StructureMap. Or why not Ninject.
In short, yes it is possible to keep the configuration at the top of the process or localized to each module. However, all dependencies must be resolved for the entire object graph in the process.
Localizing the configuration by keeping it in each module (assembly) is often a good idea because you are allowing your service layer to take responsibility for its own configuration. My answer to this question, IMHO, is a good practice.
Yes, application should have one composition root at entry point. But it can be a good practice to keep registrations of a classes inside a layer where they are implemented. Then pull these registrations from layers at composition root, registering implementations layer by layer. This is why:
Registration within layer can be redefined in other place, for
example at entry point. Most of IoC libraries work in such a way
that registration done later erases the registration done earlier.
So registration within layer defines just a default behavior which
can be easily overridden.
You don't need to reference IoC library in all your projects\layers, even if you have registrations defined inside these
layers. A very simple set of wrapper classes will allow you to
abstract away from IoC specifics anywhere except your entry point.
When your application has several entry points, reusable registration will greatly help to prevent repeating the same
registration. This copy\paste is always bad. And applications have
several entry points quite often. For example, consider the scenario
of cross-platform application having a separate entry point for
every platform it targets. Or business logic reused in web site and
in background process.
With reusable registration, you can build a very effective testing system. You will be able to run a whole layer from tests,
mock whole layers in automated way, and do it very effectively,
minimizing efforts on writing tests.
See my blog article illustrating these points in more detail, with a working sample.

Where should I define my NinjectModule and my factories?

I read a few things around on this site :
It is best to configure our container at the launch the application
It is best to avoid making our libraries dependent on a dependency injection framework
It is recommended to use factories to initialize objects whose properties are defined at the runtime
I use Ninject. If I understand these recommendations, it is necessary that:
My libraries do not use NInject.dll
Therefore, my NinjectModules must be defined in the project of my application
My factories (which are created on this principle) must also be defined in the project of my application, and not directly in the library
That seems strange, especially for factories. I have many projects that use the same library. Should all these projects redefine ninject modules and factories?
What do you think ?
The configuration does not necessarily be in the application assembly. It can also be in several dedicated assembly containing nothing than a part of the configuration. But as you mentioned it shouldn't be part of the implementation. In case you share exactly the same configuration over several projects you can reference an existing one.
For factories you can use Ninject.Extensions.Factory in the future so that you don't have to implement them yourself.
This depends a lot on the context of your libraries, how I do it is:
Initialize everything in a Bootstrapper in the main project. Although I have several levels of bootstrappers where I configure different things (mainly because I use my libraries in the same kind of projects, so they have similar configuration)
To keep this abstracted from the Ioc framework, I use the ServiceLocator pattern which you could use in your factories.

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