Using shared dependency injection in whole solution - c#

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.

Related

Configure Autofac IoC for separate projects

How should I configure Autofac so my Console Application doesn't have to add a reference to each different implementation of an interface?
I have the following project structure:
App.Core - Class library containing interfaces that will be used on the other class libraries
App.ImplA - Class library implementing interfaces from App.Core
App.ImplB - Class library implementing interfaces from App.Core
App.Console - Console Application referencing App.Core and using Autofac to inject the right reference to the implementation classes
Examples on Autofac website suggest adding the following code to the main project, which in my case is App.Console:
var builder = new ContainerBuilder();
builder.RegisterType<SomeClass>().As<ISomeInterface>().InstancePerDependency();
var appContainer = builder.Build();
But, if I want to decide which implementation class/assembly should be used via config, I won't have a reference to the assembly with the implementation (am I wrong?). Thus I won't be able to reference SomeClass on RegisterType function.
How can I do this? Is it right?
Depending on how your app and assemblies are structured, I think you have basically two options.
If all of the implementations are in the application at the same time - for example, you have both the implementations for a SQL Server data access layer and for an Oracle data access layer - then you are stuck with configuration. You may be able to make some of the typing easier by registering multiple related types in an Autofac module and then using configuration to switch modules instead of individual types. For example, all of the SQL Server type registrations would happen in one module and all of the Oracle type registrations would happen in a different module. Configuration would indicate which module to run - a one-line change instead of many lines.
If you can structure your app to only include implementations you want to use then you can use assembly scanning to do the registrations. Basically, search for all of the things implementing your interfaces and register them all on the fly. You can also combine this with Autofac modules by searching for and registering all modules found in application assemblies.

Share global Unity Container between two assemblies without passing a reference

I have two assemblies:
SERVICE - with interfaces for repositories
DB - with repository implementation
The reference direction is from DB to SERVICE (DB references SERVICE).
The SERVICE assembly creates a Unity Container. It will load DB assembly dynamically during runtime (to load implementation).
Now I need to register repository objects in the DB assembly, but I can't find any way retrieve already created Unity Container in DB assembly (instead of creating a new one what has different context).
The question is (possible solution): is there any way to get a list of already created Containers in current AppDomain (to share between asms)
I don't want to use lookup (discovery), like this:
container.RegisterTypes(AllClasses.FromLoadedAssemblies(),
WithMappings.FromMatchingInterface,
WithName.Default);
Because I want my bindings to be explicit.
You really shouldn't use (or even reference) the DI container in any of SERVICE or DB class libraries. The only place where the container should be used is the Composition Root.
The Composition Root is the entry point in an application. In your case, it is the main method of the Console Application. This is where you compose the classes from all the class libraries by registering types with the container and resolving your objects (usually a single root object).
Your class libraries shouldn't have Composition Roots. Only applications have Composition Roots. This allows other applications to use these class libraries while using different DI containers, or even without using any (which is called Pure DI).
Answering my own question but... I discovered that there are no such feature in Unity.
Possible solutions:
if assembly is referenced statically - a bootstrap method has to be invoke with reference to container, e.g. UnityConfig.Register(container);
if assembly is loaded dynamically (plugin) without any static references. Invoke the code presented in the question itself, i.e.:
container.RegisterTypes(AllClasses.FromLoadedAssemblies(),
WithMappings.FromMatchingInterface,
WithName.Default);

Create a global method to call in MVC project

I am pretty new to MVC and I am currently working on an MVC 3 project in visual studio and I want to create a method or variable that is accessible globally. When I say globally I mean available in my web project, service layer project, and data layer project.
I guess when I say global I mean global to the entire solution.
I tried creating a class in the solution items folder and referencing in my web project but its not letting me add a reference to the class since it is not a DLL.
I am a little confused with how to do this. Any suggestion would be appreciated. Also keep in mind that though I am a programmer I am still somewhat new to MVC and programming.
Edit: I have also tried adding a method in the global.asax file but was unable to call it
You should create a shared assembly where you define the class. You can then add a reference to the shared assembly from all projects that need the feature.
The class that you want to be "global" sounds like some sort of service. I suppose this is the kind of thing you may want to do with a logging service for example.
Using a logging service as an example it is generally best practice for the interface to the logging service be defined in a lightweight contracts type assembly. Then any of your assemblies that require an implementation of ILoggingService should inject the necessary implementation using an IoC container such as Autofac or MEF.
This pattern is pretty common and allows you to share common services while keeping implementations loosely coupled. Also this pattern will lead to highly testable code as fake implementations can be injected with Moq

Modular application architecture and Castle Windsor

I'm developing a .Net desktop app that interacts with scientific instruments. There are a number of variations of this instrument, each with different features, components, etc, so I've come up with a plugin/modular architecture where a "module assembly" contains all of the necessary business logic, UI, etc. to interact with that hardware component/feature.
Currently I have one solution that contains everything - the "core" application project, common libraries, plus the "module" projects. The idea is that we install the whole lot to a customer site (rather than cherry-picking which DLLs they need), and "activate" the relevant modules using a config file that contains a list of required modules.
The main application project loads the modules using Castle Windsor, using an AssemblyFilter and a custom InstallerFactory. It searches each module assembly looking for a class implementing IWindsorInstaller and decorated with a particular custom attribute (which has a property containing the module name). The module's installer will only be run if the attribute's module name is one of those requested. These installer classes are responsible for registering everything needed by that module with Windsor (business logic, views, view models, etc.).
This solution works fine in my proof of concept, however I can see a scenario where two or more modules are functionally very similar, and will therefore need to share common code. Let's say I have projects "ModuleA" and "ModuleB", and their Windsor installers registers the same IFooService class in project "ClassLibraryX". The app will fall over because IFooService has been reigstered twice, and Windsor won't know which one to resolve when requested by a constructor.
What's the best way to handle this? Thoughts so far:-
Find out if a particular component has already been registered with Windsor. This feels hacky (if possible at all)
Register components using a name, but how do I request a named instance with constructor injection?
In each module project create a new interface, such as public interface IModuleAFooService : IFooService, and register/use this throughout the project (rather than IFooService).
Any thoughts?
Edit: in fact Windsor won't fall over when it tries to resolve IFooService. It will fall over when the second module attempts to register the same interface/concrete implementation!
The way I see it, you have a couple options. I think you have two main issues. The first is that you are installing the shared interface twice (or more than that). The second is that you could have two different versions of the shared interface.
For the first issue, I would separate out the shared interfaces into their own assembly. Inside that assembly, I would have an installer that is scoped to that assembly. Then, you can tell Windsor to install that shared component and it knows how to wire itself up.
For the second issue, you have two options (as I see it). First option is that you keep your shared components backwards compatible. Second option is to isolate you runtime (through app domains or processes).
Can you not provide some meta-data for the plugin, i.e give each plugin implementation a name attribute which can be used by windsor to identify which of the implementations you want?
I have not used Castle too much recently but I am sure it did have the notion of named Bindings/Registrations, so you could use that as a way to distinguish things, if that is not going to be possible and there is no other meta data you can think of using which would make it less ambiguous for Windsor, then I would just opt with your 3rd option.
Having just read your 2nd option again (after writing the above) that seems the best option, I cannot remember EXACT syntax but in most DI frameworks you do something like:
var instance = Get<IMyInterface>("Named This");
There will be loads of syntax examples on their documentation somewhere, but you will need to know the name on both the Windsor side to register it AND on the client side to request it.
Named instances are ok. You can define dependency on concrete named service via DependsOn(Dependency.OnComponent("paramName", "serviceName")) method in fluent configuration.

How to set up Unity container in MVC application

I have troubles consuming unity container in ASP.NET MVC3 application.
I have several project with interfaces and their implementation. All interface to concreete type binding is performed in the application startup method.
I have several problems with this aproach:
1) How to handle registration of types that are not dirrectly required by MVC application but by classes that it using (Repository uses ContextManager to retrieve context instance). If this class is located in assembly that is not used by mvc app, I will have to add reference to it.
2) How to share configured container? Should I create separate assembly with static class wich will store created by mvc app container?
3) What kind of unity container usage can possibly bring cross thread problems? How to register singletons so that they will be avaliable only in this thread (web server call) etc.
You should explicitly reference all assemblies to your ASP.NET MVC application. It is the outermost layer in the onion architecture and it is allowed to know about inner layers. All assemblies must be in the bin folder anyways so the ASP.NET MVC application will know about them one way or another. Just externalize your DI framework configuration into a single place in your ASP.NET MVC application.
See 1.
Per thread storage could be dangerous in ASP.NET. Per HTTP Context is better.

Categories

Resources