Dependency Injection (DI) internally in reusable class library - c#

I have a set of projects which provide all the functionality necessary to run a .Net service. The project makes use of Dependency Inject via Ninject.
My (simplified) solution looks like this:
Project 1: Windows Service (Composition Root)
^
Project 2: Server Engine & Heavy Lifting (Ninject Module)
^
Project 3: Persistence / DAL (Ninject Module)
^
Project 4: Interfaces & Basic / Shared functionality (Interfaces)
After some significant development, turns out I will need to create a new "client" library project used to communicate with the Windows Service. This client becomes a new project (Project 5) and depends on the functionality in Project 3 and Project 4. I.e.:
Project 5: Client (Class Library)
^
Project 3: Persistence / DAL (Ninject Module)
^
Project 4: Interfaces & Basic / Shared functionality (Interfaces)
3 Immediate Problems:
I don't want to put the responsibility of wiring up an object graph on the consumer of the Client. The consumer should just use it like you have any other library you've used. You shouldn't have to worry about the internals of the library to make it work.
The Client is a class library and doesn't have an entry point of its own to consider my composition root and establish the object graph.
Even if I did have an entry point in the Client, my reading suggests I shouldn't have library dependencies on a DI framework "In that case [of creating a reusable library] you should typically make your library working without a DI container. You should yourself not take a dependency on such a container, because this would drag the container in" (from Locate the correct composition root for a .NET library). Another excerpt from a different post reads: "Only applications should have Composition Roots. Libraries and frameworks shouldn't." (from http://blog.ploeh.dk/2011/07/28/CompositionRoot/).
These problems root from the fact that I have already built much functionality into Project 3 and Project 4 that is mandatory to be used in the Client, yet these 2 projects already have a dependency on Ninject, so by proxy, the client also has a dependency on Ninject.
I can easily solve this problem using various methods, but I haven't found a resouding solution, they all feel "hacky", like I'm shoving a square peg in a round hole (What are the best practices for class libraries using dependency injection for internal operations?).

Related

Using shared dependency injection in whole solution

In my solution, I have a main project, a WebUI project, and also some supporting sub project, for example Domain for database access, quartz project for running scheduled jobs by Quartz etc.
Until recently I was using ninject successfully in the main project, but now I need to use ninject in other projects also. Can I share the dependencies inside the whole solution, meaning accessing all the beans from everywhere, or I can only access them inside a single project?
I tried to inject them to new projects, but the binding is not found :
No matching bindings are available, and the type is not self-bindable.
Is it OK, to have more then one ninject kernel inside solution assuming that each will only be used inside single Project? Or is there a better way?
I'm of the opinion that a Kernel should be one-to-one with an applications entry point. This is the Composition Root and is the place to define your Ninject Kernel so that it can resolve types for the full object graphs that will be constructed for the application. The kernel can be constructed from a collection of NinjectModule instances. The modules are where you define your bindings. If you have multiple applications that are going to use the type hierarchy you have defined I would create the bindings in custom NinjectModules that live inside your assemblies. Then depending on your application you can mix and match modules when creating your kernel. This should help in alleviating duplication of bindings in every application and they will be in a reusable location.
Specifically in your case I would:
Create a DomainModule and specify all bindings specific to your domain.
Create a QuartzModule and specify all bindings specific to job scheduling.
You can create a WebUI module as well but this would only be specific to your WebUI project which is also your composition root. As a result, it would not be re-usable in future applications. You can add your bindings directly to the kernel for this project if you want. If you have a WEB specific project, say with your controllers, etc. you may want to create a module for reference.
Compose the Kernel in your WebUI project by referencing the modules in your other applications: kernel.Load(new [] { DomainProject.DomainModule, SchedulingProject.JobModule });
Modules and the Kernel Documentation
You can, but to have it work you have to create the kernel and the bindings in every single project thay can run. so for ex if you have a web prj a domain logic prj a console app you have to create the kernel inside the web and the console. These 2 prj will reference yhe domain login prj and then it is shared.

Interfaces, business logic and global.asax with Autofac

I'm trying to figure out how separation should work with ASP.NET and dependency injection.
I have four projects:
ASP.NET Client
BusinessLogic class lib (BL)
Integration class lib, calling Service references
Shared (Interfaces, Models)
In Integration I have a repository, which calls other services. The repository "MyRepository" implements an interface "IMyRepository", which is placed in Shared, and returns objects which are also placed in Shared.
Strictly speaking, I would not like a reference/dependency from the Client to the Integration-project, but all communication should happen through BL.
In the Client's Global.asax, I register my types with Autofac
var builder = new ContainerBuilder();
builder.RegisterModule(new AutofacWebTypesModule());
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<MyRepository>().As<IMyRepository>().InstancePerHttpRequest();
However this requires the Client-project to reference the Integration-project for the implementation of MyRepository. Should it be this way?
How can I not have a reference from Client to Integration and keep the separation clean?
My real world project is on a much larger scale than this, so I'm trying to untangle the dependencies.
Thanks for your time!
My normal approach is:
Define a way to discover types in each individual assembly. Easiest approach (if you do not mind referencing Autofac in each) is to put an Autofac Module in each assembly. If you do not like that, you can define your own discovery abstraction (for example, MEF-like attributes).
Discover all assemblies. Easiest approach is to scan the bin folder, but you can use some custom configuration. I haven't checked latest versions of Autofac add anything in terms of module discovery, but previously I did it manually.
Use previously defined type discovery approach to register all relevant types from each discovered assembly.

Onion Architecture External Services

Im currently working on a project which is based on Onion Architecture . The above image Shows the Solution.
In the Infrastructure We have External Service . But the WebAPI has access only to Core .
But in the Web API project i want to access the some of the models exposed by the external services ?
How can we achieve this without adding reference to Infrastructure in the Web API .
Or we implemented Onion Architecture wrong?
conceptually you are on the right track, but the implementation isn't a hard a fast rule. to start you don't need 5+ projects at most you need 3 (web ui css/js/views, logic/controllers, code, and tests). and really you probably only need 2 (the application, the tests)
the idea of layers is conceptual, not physical. And there is not a hard and fast rule that says the layers must be completely segregated. rather the core focus of the application is what the application does. as you get into the details of how that is implemented you move to the outer layers.
in this instance you need to access data retrieved from an external service. create an abstraction for the external service IExternalServiceAdaptor. The interface may reside in the domain or server layer, but the implementation might reside in an infrastructure or outer layer where the details of how to call the external service are encapsulated within an implementation of IExternalServiceAdaptor.
If you stick with your physical separation you would have an interface in Core and the implementation in Infrstructure.
But in the Web API project i want to access the some of the models exposed by the external services ?
Actually, your WebApi project should only manipulate object defined in your Core project.
As Jason said, calls to any external services should be encapsulated within an implementation of an interface that resides in Core. And this is where models exposed by your external services will be mapped to your Core models.
Have a look at Matt Hidinger's source code on CodePlex here: http://onionarch.codeplex.com/ and check how he deals with this kind of problem, it's pretty straightforward and easy to understand.

Using IoC to resolve dynamically loaded types

I've written a program using Domain Driven Design in .NET 2.0 and I'm trying to implement a plugin framework for it.
I've implemented several types of plugins:
Domain Plugin
A domain aggregate composed of one or more domain classes
One or more View/Presenter pairs to display instances of the aggregate
An import/export service specific to the domain aggregate
A repository class
Service Plugins
Database Plugin (embedded or remote)
General import/export services (cvs, xml, competitor's data formats, etc)
As you can see, some plugins touch every layer of architecture. You could say that the domain plugins are miniature applications that simply depend on the main application to provide a framework in which to run. The ultimate goal is to let the user purchase and download only the plugins they need. I wrote them as static dependencies at first because I hadn't implemented a mechanism to load them dynamically. Now I'm trying to tackle the dynamic loading.
I'm trying to use an IoC container to manage the dependencies but I'm having difficulty working out how to find and load the plugins. In addition to the interfaces each plugin exposes to the main application, classes with each plugin also have their own interfaces they use to communicate with each other.
I'm using Castle Windsor as my IoC container and would like to take advantage of its autowiring capabilities both in the application and within each plugin as well.
How do I:
Find and load into Windsor implementations of a specific interface
Ensure Windsor resolves the correct one
If you think I'm going about this the wrong way feel free to say so. I still have time to change the design before my deadline.
I'm note sure I've understood you completly but consider looking at MEF (http://mef.codeplex.com/)
You could use something like the Managed Extensibility Framework to discover and enumerate your plugins at runtime. The plugins could then register the necessary types with your IoC container when they are discovered.

DDD Projects Structure With WCF

I'm starting a new WCF-based project which is composed by an "Engine" and some desktop applications.
But i found it difficult to make my project structure.
Engine (Windows Service, which host WCF Services for Desktop applications access and host all my business logic)
Desktop Application (Only Presentation)
Shared
MyProject.Core (Customers/Customer, Customers/ICustomerService)
Engine
MyProject.Engine (Customers/CustomerService, Customers/ICustomer, Customers/ICustomerRepository)
MyProject.Infrastructure.SqlServer (Customers/Customer (LinqToSql Specific), Customers/CustomerRepository)
WinForm Application
MyProject.Core
MyProject.UI
Am i right ?
If you are doing DDD I find it strange that you have no domain model. You have a so-called engine, which has multiple concerns. It implements your business logic and knows about hosting your business logic as a windows service.
I would propose a project structure as follows:
MyProject.Model: Defines abstract repositories, entities, value objects, services (DDD term) and other domain logic. It has no references to other projects
MyProject.DataAccess: implementation of repositories using linq2sql. Has a reference to MyProject.Model
MyProject.ServiceModel: Contains service contracts and other stuff related exposing your domain model as WCF services. this project would also contain service specific representations of those of your domain objects that the service serves and accepts. The reason for this would be that you should probably not decorate your domain classes with the attributes needed in WCF data contracts. This project references MyProject.Model.
MyProject.Service: Contains app.config for your service and performs dependency injection, through a custom ServiceHost and ServiceHostFactory. It references MyProject.Model MyProject.ServiceModel and MyProject.DataAccess + your favorite DI framework (Windsor Castle for example)
MyProject.PresentationModel: Defines various view models and commands to use in your UI. It has service references to the services exposed by MyProject.Service
MyProject.WinUI: Your WPF app. References MyProject.PresentationModel.
Note that most of what you have probably read in Eric Evans' book about DDD is only concerned with the contents of MyProject.Model. The other projects are making up additional layers not directly addressed in mr. Evans' book.
Remember that by having a clear separation of concerns, and using dependency injection you will end up with code that is easily tested. With the structure I have proposed above, you should be able to test almost everything, since your UI will contain only XAML.
Anyway, this is just my take on it. Please feel free to ask if some of this needs clarification.
Good luck with the project.
/Klaus

Categories

Resources