Share global Unity Container between two assemblies without passing a reference - c#

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);

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.

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.

Dependency injection and Libraries/Frameworks [duplicate]

This question already has answers here:
Dependency Inject (DI) "friendly" library
(4 answers)
Closed 7 years ago.
OK, maybe here is such question already, but I didn't find it..
The problem
We have big enterprise application with a lot of entry points. App contains part like:
Server
Desktop Client
Some console utilities
.NET API (separate assembly, with root class called like MyAppAPI)
COM API (the same, separate assembly, you can access to API from, for example VBScript, by Set api = CreateObject("MyApp.MyAppAPI")
Java API (again, the same)
Messaging API (separate assembly, used for communicating between layers through messages queues)
We use Unity as DI container in this app. Everything is cool in Server/DesktopClient/Console utilities etc. - there are very concrete entry points, so we just initialize composition root object there, initialize tree of objects/dependencies, and everything works like a charm. Them problem is with our APIs.
#1
How to deal with DI in libraries/frameworks?
From the link above:
The Composition Root is an application infrastructure component.
Only applications should have Composition Roots. Libraries and
frameworks shouldn’t.
Yeah, it's cool, but.. I want to use DI in my API, it's huge! How to deal one with other?
#2
We have dependencies, which preferably should be singletons (e.g. some factories, which control lifetime of created objects). But, we can create some instances of API objects, how to share this singleton instances between them? Even more - we can create some instances of .NET API objects and one/some instances of COM API objects in the same domain (if you want, I can explain in the comment when it's possible)..
What I have now
As I said, there is no problem with apps, the problem exists in libraries (APIs). So, what I have now
I have class ShellBase
this class contains static field _Shells and public static methods Get and Release
there is hierarchy between containers (e.g. APIs' containers are inherited from MessagingAPI, Server and DesktopClient containers are inherited from .NET API container etc.)
when somebody ask for new shell (through Get method), ShellBase checks if there is already such container (or super-container, from subclass), and returns that instance. Or creates new one
I don't like this way, but this is the best what I can imagine right now.
Possible solution
Create something like APIFactory, which will create our API objects, but it looks.. too complicated for end-users. I don't want to write in user documentation: "Please, create and keep APIFactory instance first, then you can create API instances using this factory". It's ugly. Our users should write just var api = new API(), and use it.
So, guys, what do you think?
1: I have seen other frameworks/libraries where they introduce their own DI container abstraction, via an interface. They then use this interface internally wherever they need to reference the DI container. Adapters are used to connect their library with a specific DI container. For example, Davy Brion's Agatha project has the following Container interface: https://github.com/davybrion/Agatha/blob/master/Agatha.Common/InversionOfControl/IContainer.cs and he supplies adapters for the most used DI containers.
2: Im not entirely sure I understand your problem here, but most, if not all, DI containers support singleton lifetime scopes, meaning your container will only ever create a single instance. For example, in ninject you would do:
kernel.Bind<IFoo>()
.To<Foo>()
.InSingletonScope();
Alternatively, if you want to avoid public constructors, you can make a static singleton instance of the class like you would do without a DI container. You can the register your singleton instance with the container with a factory method that returns that instance. Again, a ninject example:
kernel.Bind<IFoo>()
.ToMethod(c => Foo.Instance);
Given the interface introduced above, you should be able to share a single container instance between your APIs (assuming you use more than one API in a given application), thereby enforcing the singleton requirement.
If this is not your problem, then maybe you can elaborate on the second problem.

IOC in Winforms plugin architecture

I am working with an architecture that has a main program. When this starts it looks in the executing path via reflection for DLL's that have inherited off a base class. These are the plugins.
When a new requirement for a new project arises typically a new plugin is created. This plugin has the main plugin class and then possibly a number of other classes and windows forms.
The main plugin class has initialize methods but as its a class library there is no program.cs so to speak to wire up dependencies.
Is there a way via an app.config to wire up dependencies or do you think I should avoid using an IOC Container and just have a factory method in the plugin class that wires up the dependencies some how?
The issue is I may not have the ability to change the main application's code to setup the IOC container
All major IoC containers have the ability to wire up dependencies with app.config or via an assembly discovery mechanism (like you describe). Typically the main application sets up the container, and then defers to the container to find the plugins (which may be configured via configuration or by assembly probing like you describe above).
For SpringFramework.net, as an example of app.config: http://www.springframework.net/doc-latest/reference/html/objects.html#d4e437
For Castle Windsor, an example of assembly probing: http://stw.castleproject.org/Windsor.Installers.ashx
Whilst I think your question is a bit vague, based on what I gather from your question I would have to say IoC would most likely be the best way to go! You can use your IoC container to wire up the factories if you like, or you can use it to wire up the PlugIn dependencies, Personally, I like to use StructureMap. A very versatile and easy to use IoC container.
You could use the app.config to list the dependancy names and then feed the IoC the names to create dependencies. Use something like Activator to then create instances. Personally, I would use both IoC and factories. I would use the app.config to specify the dependency names and then use a Factory to dish out the instances of the plugIn classes. And finally I would then use the IoC container to specify the implementation of the factory(ies).
Hope that is of some use!

Categories

Resources