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.
Related
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);
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
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.
I am new to using castle windsor. I have it set up and functioning correctly in my MVC4 app. For brevity the impacted layout of my solution is:
Entities.dll
- ICompanyRepository
DAL.dll
- Company : ICompanyRepository
Basically I have a bunch of classes and interfaces set up like above so I can switch out the DAL if need be with another repository. I have currently registered the class and interface with Castle Windsor by using the following:
container.Register(Component.For<Entities.ICompanyRepository>().ImplementedBy<DAL.Company>().LifestyleTransient());
My interface and class that implements it are in separate projects and therefore dlls in my project. What I would like to do but cannot figure out is to use one blanket configuration line like the above:
container.Register(AllTypes.FromAssemblyNamed("Entities"));
I have tried many different combinations but I can't get it working. Any ideas? I am open to loading from a config file if that is better option.
I assume all your repositories are implementing a common interface such IRepository, if not you should do so not just for IoC purpose...
that you can use following registration in order to register all component based on a common interface.
Installer should be located in the entry-point project so it should be able to see any other projects/dll.
container.Register(Classes
.FromAssemblyNamed("DAL")//assembly containing concrete types
.BasedOn(typeof(IRepository<>))
.WithService.DefaultInterfaces()//concrete will be associated(windosr configuration) with closest interface
.Configure(c => c.YourPolicystrategy()));
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.