Dependency injection and Libraries/Frameworks [duplicate] - c#

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.

Related

UWP MVVM Template10: Access single instance of external API across application

I've been tasked with taking over a partially developed sizeable and complex UWP application using MVVM via Template 10. The app needs to use an in-house developed webservices API and this needs to be used for practically every single function, starting with the initial login page.
So given I need to access a single instance of the API everywhere how do I go about doing that correctly? I've used MVVM a fair bit but never used Template10 and never had to share an instance of an object across an entire MVVM UWP app before.
So far I can think of three ways:
Declare and instantiate API instance in Appl.xaml.cs and use it globally
Create a public Globals class and have the instance as a public static property:
c#
public class Globals
{
private static OurAPI _ourAPI;
public static OurAPI API
{
get { return _ourAPI; }
set { _ourAPI = value; }
}
}
Instantiate the API in the login page and then pass it as a parameter between ViewModels, presumably using the Navigation service.
I'm thinking 1 or 2 are most likely not MVVM compliant and could cause unit testing issues so maybe 3 is the best option? Or is there another, more correct way to do this to adhere to Template10/MVVM concepts and also be able to unit test it?
EDIT: Sorry about the code not formatting, the edit box formats it Ok but when I save it it goes back to one long sentence :-(
The best solution consists of a singleton service and inversion of control (IoC) / Dependency injection . This is a pretty complex topic so I definitely encourage to read about it from several sources.
In summary, you first create an interface for your service, where you declare all the public members and methods. Then you create an implementation of the interface. Then you use a IoC container and register your service as a singleton (single-instance) and then integrate the IoC so that it creates instances of your view models. Then you can put the interface as a constructor parameter of your view model and the IoC container will make sure to provide the singleton instance you registered.
In your case, you are using Template 10 which can be integrated with different IoC containers as seen in the documentation. Check out AutoFac as an example of an IoC container. You can see some examples of registering and resolving a service in the documentation.
For a general solution, check this SO question which demonstrates using AutoFac in UWP.
You can also see some code examples in this SO question and this one specifically for Template 10.
This solution is better than using static and global instances because you never actually deal with any hardcoded reference and actually always work just against the interface. You put the interface as the parameter of your constructor and IoC will take care of providing the instance for you. In addition - you can anytime swap the interface implementation for a different class and you just have to update it in one single location - the IoC registration.

Best practices for Inversion of Control in libraries? [duplicate]

This question already has answers here:
Dependency Inject (DI) "friendly" library
(4 answers)
Closed 5 years ago.
I've been tasked with establishing code patterns to use for new applications that we'll be building. An early decision was made to build our applications and libraries using Prism & MEF with the intent of simplifying testing & reuse of functionality across applications.
As our code base has grown I've run into a problem.
Suppose we have some base library that needs access to some system - let's say a user management system:
public interface IUserManagementSystem
{
IUser AuthenticateUser(string username, string password);
}
// ...
public class SomeClass
{
[ImportingConstructor]
public SomeClass(IUserManagementSystem userSystem){ }
}
We can now create an object of type SomeClass using the ServiceLocator, but ONLY if an implementation of IUserManagementSystem has been registered. There is no way to know (at compile-time) whether creation will succeed or fail, what implementations are needed or other critical information.
This problem becomes even more complicated if we use the ServiceLocator in the library.
Finding the now-hidden dependencies has become a bigger problem than hard-coded dependencies were in legacy applications. The IoC and Dependency Injection patterns aren't new, how are we supposed to manage dependencies once we take that job away from the compiler? Should we avoid using ServiceLocator (or other IoC containers) in library code entirely?
EDIT: I'm specifically wondering how to handle cross-cutting concerns (such as logging, communication and configuration). I've seen some recommendations for building a CCC project (presumably making heavy use of singletons). In other cases (Is the dependency injection a cross-cutting concern?) the recommendation is to use the DI framework throughout the library leading back to the original problem of tracking dependencies.
Dependency Inject (DI) "friendly" library is somewhat relevant in that it explains how to structure code in a manner that can be used with or without a DI framework, but it doesn't address whether or not it makes sense to use DI within a library or how to determine the dependencies a given library requires. The marked answers there provide solid architectural advice about interacting with a DI framework but it doesn't address my question.
You should not be using ServiceLocator or any other DI-framework-specific pieces in your core library. That couples your code to the specific DI framework, and makes it so anyone consuming your library must also add that DI framework as a dependency for their product. Instead, use constructor injection and the various techniques mentioned by Mark Seeman in his excellent answer here.
Then, to help users of your library to get bootstrapped more easily, you can provide separate DI-Container-specific libraries with some basic utility classes that handle most of the standard DI bindings you're expecting people to use, so in many cases they can get started with a single line of code.
The problem of missing dependencies until run-time is a common one when using DI frameworks. The only real way around it is to use "poor-man's DI", where you have a class that actually defines how each type of object gets constructed, so you get a compile-time error if a dependency is introduced that you haven't dealt with.
However, you can often mitigate the problem by checking things as early in the runtime as possible. For example, SimpleInjector has a Validate() method that you can call after all the bindings have been set up, and it'll throw an exception if it can tell that it won't know how to construct dependencies for any of the types that have been registered to it. I also like adding a simple integration test to my testing suite that sets up all the bindings and then tries to construct all of the top-level types in my application (Web API Controllers, e.g.), and fails if it can't do so.

MVC4 C# Project: Provide a single instance of an object across the application

Background
I am going to provide the background here before posing my actual question:
I am working on an ASP.NET MVC 4 project in C#. The current development task I am busy with is to implement RazorMachine (https://github.com/jlamfers/RazorMachine) in this web application in order to leverage the use of the Razor engine in my application layer (as opposed to purely in the MVC web layer). I have successfully implemented RazorMachine in a series of Test Fixtures and all is working great. Now, I need to implement it into my application architecture inside my application layer.
In his CodeProject article on RazorMachine (http://www.codeproject.com/Articles/423141/Razor-2-0-template-engine-supporting-layouts), Jaap Lamfers states "Please note that normally for performance reasons at any application you would create a singleton instance of RazorMachine (because of the inner instance bound JIT created type caching)".
A very basic example of the code in action is as follows:
RazorMachine rm = new RazorMachine();
ITemplate template = rm.ExecuteContent("Razor says: Hello #Model.FirstName #Model.LastName",
new {FirstName="John", LastName="Smith"});
Console.WriteLine(template.Result);
You can view more code samples on the CodeProject site.
With this as background, my question is as follows:
What is the best way to provide a single instance of the RazorMachine object to my MVC application?
Let me state that I am aware of the Singleton and Factory patterns and their possible implementations. However, using Singleton doesn't seem to sit right as I am not writing the class from scratch, the class already exists. Factory also seems to not be wholly appropriate, but I would like to hear what others say.
All input will be greatly appreciated.
THe quickest, easiest way to get a singleton instance of RazorMachine is to use your DI container of choice, examples of well known DI containers are Autofac, Ninject, Castle Windsor, Unity, StructureMap (see this link for a performance comparision of major .NET Ioc/DI containers: http://www.palmmedia.de/blog/2011/8/30/ioc-container-benchmark-performance-comparison)
These containers abstract away from you the developer the responsibility to correctly implementing the Singleton pattern.
Using Autofac, to register a singleton instance of a class you would do the following:
var builder = new ContainerBuilder();
builder.RegisterType<YourClassGoesHere>().SingleInstance();
Ref:http://autofac.readthedocs.org/en/latest/lifetime/instance-scope.html#single-instance

How to use dependency injection in enterprise projects

Imagine you have an application with several hundreds of classes implementing dozens of "high level" interfaces (meaning component level). Is there a recommend way of doing dependecy injection (like with unity). Should there be a "general container" that can be used for bootstrapping, accessible as a Singleton? Should a container be passed around, where all instances can RegisterInstance? Should everything be done by RegisterType somewhere in the startup? How can the container be made accessible when needed. Constructor injection seems false, controverse of being the standard way, you have to pass down interfaces from a component level to the very down where it is used right on startup, or a reference is hold ending up in a "know where you live" antipattern.
And: having a container "available" may bring developers to the idea of resolving server components in client context. how to avoid that?
Any discussion welcome!
edit for clarification
I figured out a somewhat realworld example to have a better picture of what problems i see.
lets imagine the application is a hifi system.
the system has cd player (integrated in a cd-rack) and
an usb port (integrated in an usb rack) to play music from.
now, the cd player and the usb port shall be able to play mp3 music.
i have an mp3 decoder somewhere around, which is injectable.
now i start the hifi system. there is no cd inserted yet and
no usb stick pluged in. i do not need a mp3 decoder now.
but with constructor injection, i have to already inject
the dependency into the cd rack and the usb rack.
what if i never insert a mp3 cd or an mp3 usb stick?
shall i hold an reference in the cd rack, so when an mp3 cd
is inserted, i have a decorder on hand? (seems wrong to me)
the decoder is needed in a subsystem of the cd rack, which
is only started if a mp3 gets inserted. now i have no container
in the cd rack, what about constructor injection here?
First of all, Dependency Injection is a design pattern that does not require a container. The DI pattern states:
Dependency injection is a software design pattern that allows a choice of component to be made at run-time rather than compile time
Take for example Guice (java dependency injection framework), in Java Guice is a DI framework but it is not a container itself.
Most of the DI tools in .Net are actually containers, so you need to populate the container in order to be able to inject the dependency
I do not like the idea to have to register every component every time in a container, I simply hate that. There are several tools that help you auto register components based on conventions, I do not use Unity, but I can point you for example to Ninject or AutoFac
I am actually writing a small utility to auto register components based on conventions using practically any DI tool, it is still in dev phase
About your questions:
Should there be a "general container" that can be used for bootstrapping, accessible as a Singleton?
The answer is yes, (there's a tool to abstract the DI tool used, it is called ServiceLocator) that's how DI tools work, there is a static container available to the application, however, it is not recommended to use it inside the domain objects to create instances, that's considered an anti-pattern
BTW I have found this tool really useful to register components at runtime:
http://bootstrapper.codeplex.com/
Should a container be passed around, where all instances can RegisterInstance?
No. that would violate the law of Demeter. If you decide to use a container is better to register the components when the application starts
How can the container be made accessible when needed
Well using the Common Service Locator you could use it anywhere in your application, but like I said, it is not recommended to use it inside the domain objects to create the required instances, instead, inject the objects in the constructor of the object and let the DI tool to automatically inject the correct instance.
Now based on this:
Constructor injection seems false, controverse of being the standard way, you have to pass down interfaces from a component level to the very down where it is used right on startup, or a reference is hold ending up in a "know where you live" antipattern
Makes me think that you are not writing unit tests heavily for your application which is bad. So my suggestion is, before choosing between which DI tool you are going to use, or before taking all the answers you get to this question into consideration, refer to the following links which are focus on one thing: Write clean testable code, this is by far the best source you could get to answer yourself your own question
Clean Code talks:
http://www.youtube.com/watch?v=wEhu57pih5w&feature=player_embedded
http://www.youtube.com/watch?v=RlfLCWKxHJ0&feature=player_embedded
Articles
http://misko.hevery.com/2010/05/26/do-it-yourself-dependency-injection/
http://misko.hevery.com/code-reviewers-guide/
Previous link in PDF http://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf
The following links are super highly recommended
http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/
http://www.loosecouplings.com/2011/01/how-to-write-testable-code-overview.html
First, there is the Composition Root pattern, you set up your dependencies as soon as possible, Main() in desktop, global.asax/app_start in web. Then, rely on constructor injection as this makes your dependencies clear.
However, you still need something to actually RESOLVE dependencies. There are at least two approaches known to me.
First one consist in using the Service Locator (which is almost equal to making the container a singleton). This is considered an antipattern for a lot of people, however it just works great. Whenever you need a service, you ask your container for it:
... business code...
var service = ServiceLocator.Current.GetInstance<IMyService>();
service.Foo();
Service Locator just uses a container you set up in the Composition Root.
Another approach consist in relying on object factories available as singletons with the container injected into them:
var service = IMyServiceFactory.Instance.CreateService();
The trick is that implementation of the factory uses the container internally to resolve the service. However, this approach, with an additional factory layer, makes your business code independent and unaware of the IoC! You are free to completely redesign the factories to not to use IoC internally and still maintain every single line of business code.
In other words, it's just a trick then to hide the container/locator behind a factory layer.
While tempted to use the former approach (rely directly on the locator) I prefer the latter. It just feels cleaner.
I wonder if there are other viable alternatives here.
Should a container be passed around
No, since this leads to the Service Locator anti-pattern.
where all instances can RegisterInstance
Services should be registered in the start-up path of the application, not by types themselves. When you have multiple applications (such as web app, web service, WPF client), there will often be a common bootstrapper project that wires all services together for shared layers (but each application will still have its unique wiring, since no application behaves the same).
Should everything be done by RegisterType somewhere in the startup
Yes, you should wire everything up at start-up.
How can the container be made accessible when needed.
You shouldn't. The application should be oblivious to the use of a container (if any container is used, since this is optional). If you don't do this, you will make a lot of things much harder, such as testing. You can however, inject the container in types that are defined in the startup path of the application (a.k.a. the Composition Root). This way the application keeps clean from knowing anything about the container.
Constructor injection seems false, controverse of being the standard way
Constructor injection is the prefered way of injecting dependencies. However, it can be challanging to refactor an existing application towards constructor injection. In **rare* circumstances where constructor injection doesn't work, you can revert to property injection, or when it is impossible to build up the complete object graph, you can inject a factory. When the factory implementation is part of the composition root, you can let it depend on the container.
A pattern I found very useful, that can be built on top of the Dependency Injection pattern and the SOLID design principles, is the command / handler pattern. I found this a useful pattern in smaller apps, but it will shine when applications get big, such as enterprise applications.
now i start the hifi system. there is no cd inserted yet and no usb
stick pluged in. i do not need a mp3 decoder now.
This seems like a perfect fit for Setter injection (=property injection in C#). Use a NeutralDecoder or NullDecoder as a default and inject an Mp3Decoder when you need it. You can do it by hand or using a DI container and conditional/late binding.
http://blog.springsource.com/2007/07/11/setter-injection-versus-constructor-injection-and-the-use-of-required/
We usually advise people to use constructor injection for all
mandatory collaborators and setter injection for all other properties.

Is an IoC container an overkill for a very simple framework

I am creating a library that integrates our product with another 3rd party product.
The design being used involves an interface that abstracts the core operations i'd like to integrate to our product, such that when a new 3rd party API is released, we would transparently switch to using it instead of the old one without modifying existing code.
To this end, the actual code that will return a concrete instance of the object interacting with 3rd party API needs to make a decision on to "which implementation to select".
For the simple needs, i assume an entry in the configuration file would suffice to say the fully qualified implementing class name.
Should i use an IoC container in this case, or should i use a Factory Method pattern and code it myself? (use reflection to instantiate the object, etc).
What are the pros and cons for this? Am i missing anything?
Quoting Mark Seemann:
Applications should depend on containers. Frameworks should not.
An IoC container sounds like overkill for your problem. If you have only one dependency to inject, doing it via the config file should be just fine.
Any IoC container is never overkill. You WILL eventually expand on this app if it's successful, or at the least used regularly and you will get requests to add more.
I'm a Castle user, and it's darn easy to add Castle with NuGet then just create a new WindsorContainer() in the startup and register your interfaces and class.
It's like asking if TDD is overkill to make a simple app. You should always (if you can) TDD the app, and use interfaces over concrete in your classes. IoC is too easy to setup now that you're only adding a few lines of code, so why not? it will be much harder later on if you didn't originally use an IoC container and you have intefaces and newed up classes all over your project to organize them all back into an IoC container.

Categories

Resources