Why use services (IServiceProvider)? - c#

I'm coming to this question from exploring the XNA framework, but I'd like a general understanding.
ISomeService someService = (ISomeService)Game.GetServices(typeof(ISomeService));
and then we do something with whatever functions/properties are in the interface:
someService.DoSomething(); // let's say not a static method but doesn't matter
I'm trying to figure out why this kind of implementation is any better than:
myObject = InstanceFromComponentThatWouldProvideTheService();
myObject.DoSomething();
When you use the services way to get your interface, you're really just getting an instance of the component that provides the service anyway. Right? You can't have an interface "instance". And there's only one class that can be the provider of a service. So all you really have is an instance of your component class, with the only difference being that you only have access to a subset of the component object (whatever subset is in the interface).
How is this any different from just having public and private methods and properties? In other words, the public methods/properties of the component is the "interface", and we can stop with all this roundaboutness. You can still change how you implement that "interface" without breaking anything (until you change the method signature, but that would break the services implementation too).
And there is going to be a 1-to-1 relationship between the component and the service anyway (more than one class can't register to be a provider of the service), and I can't see a class being a provider of more than one service (srp and all that).
So I guess I'm trying to figure out what problem this kind of framework is meant to solve. What am I missing?

Allow me to explain it via an example from XNA itself:
The ContentManager constructor takes a IServiceProvider. It then uses that IServiceProvider to get a IGraphicsDeviceService, which it in turn uses to get a GraphicsDevice onto which it loads things like textures, effects, etc.
It cannot take a Game - because that class is entirely optional (and is in a dependent assembly). It cannot take a GraphicsDeviceManager (the commonly used implementation of IGraphicsDeviceService) because that, like Game is an optional helper class for setting up the GraphicsDevice.
It can't take a GraphicsDevice directly, because you may be creating a ContentManager before the GraphicsDevice is created (this is exactly what the default Game class does). So it takes a service that it can retrieve a graphics device from later.
Now here is the real kicker: It could take a IGraphicsDeviceService and use that directly. BUT: what if at some time in the future the XNA team adds (for example) an AudioDevice class that some content types depend on? Then you'd have to modify the method signature of the ContentManager constructor to take an IAudioDeviceService or something - which will break third-party code. By having a service provider you avoid this issue.
In fact - you don't have to wait for the XNA team to add new content types requiring common resources: When you write a custom ContentTypeReader you can get access to the IServiceProvider from the content manager and query it for whatever service you like - even your own! This way your custom content types can use the same mechanism as the first-class XNA graphics types use, without the XNA code having to know about them or the services they require.
(Conversely, if you never load graphics types with your ContentManager, then you never have to provide it with a graphics device service.)
This is, of course, all well and good for a library like XNA, which needs to be updatable without breaking third-party code. Especially for something like ContentManager that is extendible by third parties.
However: I see lots of people running around using DrawableGameComponent, finding that you can't get a shared SpriteBatch into it easily, and so creating some kind of sprite-batch-service to pass that around. This is a lot more complication than you need for a game which generally has no versioning, assembly-dependency, or third-party extensibility requirements to worry about. Just because Game.Services exists, doesn't mean you have to use it! If you can pass things (like a SpriteBatch instance) around directly - just do that - it's much simpler and more obvious.

See http://en.wikipedia.org/wiki/Dependency_inversion_principle (and it's links) for a good start as to the architectural principles behind it

Interfaces are clearer and easier to mock.
That can be important, depending on your unit test policy.

Using a service provider is also a way of better controlling what portions of your code have access to certain other portions of your code. Similarly to passing an object through your code, you can pass an IServiceProvider implementation through the code to specific modules. This would allow for those modules to access certain services that are accessible through the service provider.
You can have many classes implement the IServiceProvider interface, each of which could provide access to one or more services - they are not restricted to returning a single instance (whether that be to themselves or another object).
For example, a use may be to have an IServiceProvider that contains services for keyboard handling, mouse handling and AI algorithms. Passing this interface to different modules or managers within your code will allow those modules or managers to retrieve the services they require (such as an EnemyManager needing access to the AI service).

Related

The Dependency Inversion Principle with .NET Framework classes

I'm trying to understand SOLID principles, in particular The Dependency Inversion Principle.
In this is SO answer it is explained very well.
I think I have understood that I can't create any instance of a class inside my class. Is it right?
But if I have to save to disk some content, can I create an instance of System.IO.File or do I have to inject it?
I don't understand where is the limit, if I can't instance my own classes or if I can't either instance .NET Framework classes (or whatever other framework).
UPDATE:
I think File is a bad example because is declared as static.
By the way, does this principle apply to static classes?
The S of SOLID stands for SRP (Single Responsibility Principle). You won't violate it by using System.IO.File inside a class directly, once you keep that class with one single responsibility.
It's a good idea trying to abstract the purpose behind using System.IO.File. Let's suppose you need it to generate a log. Then you would probably do something like:
public interface IMyLogger
{
void GenerateLog(IEnumerable<string> content);
}
public class FileLogger: IMyLogger
{
public void GenerateLog(IEnumerable<string> content)
{
System.IO.File.WriteAllLines("C:/Log", content);
}
}
Maybe it's not just a log, it's something more important, like generating a file so other system/app (even external) read it and do some job.
If you are trying to use a DDD approach, the interface could belong to your domain, and the implementation could belong in the application. Then you register your interface as a service and inject it.
The class which needs an IMyLogger actually doesn't need to know how is the log being generated, it just needs the job to be done.
You can apply the same idea when you need to send an email inside some business logic in your domain. Instead of making a connection to an Exchange inside your domain directly, create an interface INotifier and a MailNotifier implementing it to be injected.
Somewhere down the chain of dependencies you will need to use the concrete class directly. Even if you use a DI framework like Ninject, the framework itself will create an instance of the concrete type, so it will not be injected into the framework (which wouldn't make sense, of course).
You can only abstract something away to a certain level. It will vary from project to project - you have to ask yourself if you need another level of abstraction (be it for modularity, unit testing etc.). I think this is very important - you want to be pragmatic, not create layers upon layers of abstractions just for the sake of it.
By the way, does this principle apply to static classes?
Yes, it does. But with static classes you have to introduce a wrapper, which will delegate calls to the static class, because a static class cannot implement interfaces.
There is no point in applying a principle just for the sake of it. Think in a pragmatic way.
If you want to unit-test a method that uses hard coded file accesses, your unit tests will access these files. This is usually not desired as you must set up or clean up these files. To avoid this, you would inject a service which wraps these file accesses. This allows you to replace the real service with a fake one during the unit tests. This fake service can provide hard coded test data for read accesses and dump written data to memory for later analysis or simply do nothing. Btw.: NSubstitute can create fake services at runtime easily.
The injection of services allows you to achieve Unit Test Isolation. E.g. you can test some logic without depending on correct file handling or database accesses or the correct functioning of other services. Injecting a service is just one way to do it. You could also just specify a method parameter as IEnumerable<string> with the content of the file instead. Events can also be used for decoupling. Instead of writing to a log, you could raise a log event.
Most DI frameworks allow you to specify the lifetime of objects. One of these options is Singleton, which means that the DI container will always return the same instance of a requested service. This allows you to wrap static classes in a service that behaves statically.

Castle Windsor injection of specific component

I might be overthinking this. I hope so.
In our .Net 4.5, C# 5 Windows service, we're using Castle Windsor 3.2 with the CollectionResolver installed. We have an interface IEncryptionService that does what you'd expect, and two classes implement that interface. The service needs to integrate and bridge two other systems, by decrypting data from one and re-encrypting it for the other.
Both implementations have names according to their target system.
Component.For<IEncryptionService>()
.ImplementedBy<System1EncryptionService>()
.Named("system1-encryption")
.LifestyleTransient(),
Component.For<IEncryptionService>()
.ImplementedBy<System2EncryptionService>()
.LifestyleTransient()
.Named("system2-encryption"));
The Windows service class uses constructor injection to receive an array of type IEncryptionService[]. Both of the encryption classes are being injected.
Therein lies the problem: I need to use one implementation for one system, and the other for the other. The way I've implemented it thus far, they're indistinguishable from each other.
What is the solution here? A typed factory seems like an anti-pattern covering up an architectural flaw. But its the only thing I've come up with. I've named my components; can I take advantage of that in other components? Or should I just forget injection and instantiate them directly?
I figure this sort of situation happens often enough that there's probably a standard way of handling it.
When you register your component which depends on the two, you specify the names of the arguments corresponding to the injected classes in the Compnent.For line:
Component.For<IServiceUsingTheEncryption>()
.ImplementedBy<ServiceUsingTheEncryption>()
//.LifestyleOfYourChoosing
.ServiceOverrides(
ServiceOverride.ForKey("encryptionService1").Eq("system1-encryption"),
ServiceOverride.ForKey("encryptionService2").Eq("system2-encryption"));
And in the ctor of your ServiceUsingTheEncryption, you would specify the arguments as such:
public ServiceUsingTheEncryption(IEncryptionService encryptionService1, IEncryptionService encryptionService2) {
// ...
}

Intercept ALL services

We have small lifetime scopes in our applications. It would be interesting to be able to intercept all services registered in autofac. By doing so we can see exactly which path the code takes for every lifetime scope and which method arguments are used. Not really usable for production but when really great for debugging/diagnostics/refactoring as you ge the whole picture and not just unit level.
But AFAIK it's only possible to register an interceptor for each single registration?
Nothing like this is supported out of the box with the Autofac.Extras.DynamicProxy2 library. You could potentially implement something like a module that handles OnActivating for every component using code similar to the stuff in Autofac.Extras.DynamicProxy2, but you'll run into trouble like...
Do you want class interceptors or interface interceptors? The type of service being resolved vs. the limit type of the component backing it will influence what kind of dynamic proxy you want to make. I believe the current A.E.D2 code only generates interception for either/or - not every interface a class implements, etc.
Do you use WCF client proxies? Client proxies are an interesting beast of their own so you have to special-case them. You'll see that in A.E.D2.
Generally problems like this get solved by aspect-oriented programming solutions (e.g., PostSharp) or profilers (e.g., ANTS)... or a combination of both. You might want to look into those solutions if you have the ability.
For an example of what sort of module implementation I'm talking about, check out the log4net integration page on the Autofac wiki. That shows how to handle OnPreparing for every component in the system. You can do the same thing, but handle OnActivating instead and use the sample on the Lifetime Events wiki page to show you how to swap one resolved thing for another (swap the real object for the generated proxy).

What framework uses `IServiceProvider`?

Is the IServiceProvider basically just a generic interface for any IOC container, or is it used for a specific framework? I'm rolling my own light weight IOC container and I am wanting to know if I should implement it. Are there any other interfaces that I should implement? I'm not really interested in either MEF or Unity. I've used both extensively and they don't really work for my current project.
IServiceProvider is an imported (or perhaps held-over) COM interface that is intended to be used for private features in the context of the object whom you interrogate for a Service. The term 'Service' is applied rather loosely here, it originally meant any COM object that could be returned based upon what GUID is given.
IServiceProvider # MSDN (.NET reference)
IServiceProviderImpl Class # MSDN (C++ ATL reference)
In .NET, you don't need to implement it unless you have a client that specifically supports it, and in many cases you won't need to add yet another level of indirection that is implied by using IServiceProvider. Also, you can devise your own scheme to share common objects or implement other use patterns based upon IoC / Dependency Injection that are more flexible or more rigid as dictated by your needs.
One good historical context for IServiceProvider is the IE Browser Plugin Spec. Here, it is used to allow plugin components to use Browser Host features in-context. In a COM context, this interface is useful because it hides the details of instantiation and also can be used as part of a object construction and utilization strategy to avoid reference loops.
WebBrowser Customization (Part 2) # MSDN
I think it is a pretty general use interface, so you can use it with anything. It almost should not even be in the Framework Class Library. For one specific use, Alex D. James of the WCF Data Services team has a blog about it.
http://blogs.msdn.com/b/alexj/archive/2010/01/07/creating-a-data-service-provider-part-2-iserviceprovider-datasources.aspx
I do not think it has anything to do with IoC containers. I have used Unity and Autofac quite a bit and have never seen it used with either. As for rolling your own, I would suggest you define your own container interface in the more standard generic way:
public interface IContainer
{
T Resolve<T>();
}
That is pretty standard with some variation, but you could also just use IServiceProvider if that fits your needs.
And on that note, unless this is just an academic exercise, you might want to read "Dependency Injection". Mark Seemann covers every container out there and quite a bit of theory and practice. That is, I highly recommend it.
https://www.amazon.com/Dependency-Injection-NET-Mark-Seemann/
ASP.NET 5 uses IServiceProvider in "self-hosted" mode, that is, when hosting an ASP.NET application and the runtime in a console application or service.
(An object of type Microsoft.Framework.Runtime.Common.DependencyInjection.ServiceProvider -- which implements IServiceProvider -- is passed to your console app constructor.)
Thus, if you wanted to use a different IoC container in ASP.NET 5, you might want to implement this interface. Or wrap the other IoC container in a class which implements this interface.
The new (as of .NET 4) Runtime Caching API also uses it: http://msdn.microsoft.com/en-us/library/system.runtime.caching.objectcache.host.aspx.
And also Visual Studio designer.

Does Dependency Injection (DI) rely on Interfaces?

This may seem obvious to most people, but I'm just trying to confirm that Dependency Injection (DI) relies on the use of Interfaces.
More specifically, in the case of a class which has a certain Interface as a parameter in its constructor or a certain Interface defined as a property (aka. Setter), the DI framework can hand over an instance of a concrete class to satisfy the needs of that Interface in that class. (Apologies if this description is not clear. I'm having trouble describing this properly because the terminology/concepts are still somewhat new to me.)
The reason I ask is that I currently have a class that has a dependency of sorts. Not so much an object dependency, but a URL. The class looks like this [C#]:
using System.Web.Services.Protocols;
public partial class SomeLibraryService : SoapHttpClientProtocol
{
public SomeLibraryService()
{
this.Url = "http://MyDomainName.com:8080/library-service/jse";
}
}
The SoapHttpClientProtocol class has a Public property called Url (which is a plain old "string") and the constructor here initializes it to a hard-coded value.
Could I possibly use a DI framework to inject a different value at construction? I'm thinking not since this.Url isn't any sort of Interface; it's a String.
[Incidentally, the code above was "auto-generated by wsdl", according to the comments in the code I'm working with. So I don't particularly want to change this code, although I don't see myself re-generating it either. So maybe changing this code is fine.]
I could see myself making an alternate constructor that takes a string as a parameter and initializes this.Url that way, but I'm not sure that's the correct approach regarding keeping loosely coupled separation of concerns. (SoC)
Any advice for this situation?
DI really just means a class wont construct it's external dependencies and will not manage the lifetime of those dependencies. Dependencies can be injected either via constructor, or via method parameter. Interfaces or abstract types are common to clarify the contract the consumer expects from its dependency, however simple types can be injected as well in some cases.
For example, a class in a library might call HttpContext.Current internally, which makes arbitrary assumptions about the application the code will be hosted in. An DI version of the library method would expect a HttpContext instance to be injected via parameter, etc.
It's not required to use interfaces -- you could use concrete types or abstract base classes. But many of the advantages of DI (such as being able to change an implementation of a dependancy) come when using interfaces.
Castle Windsor (the DI framework I know best), allows you to map objects in the IoC container to Interfaces, or to just names, which would work in your case.
Dependency Injection is a way of organizing your code. Maybe some of your confusion comes from the fact that there is not one official way to do it. It can be achieved using "regular" c# code , or by using a framework like Castle Windsor. Sometimes (often?) this involves using interfaces. No matter how it is achieved, the big picture goal of DI is usually to make your code easier to test and easier to modify later on.
If you were to inject the URL in your example via a constructor, that could be considered "manual" DI. The Wikipedia article on DI has more examples of manual vs framework DI.
I would like to answer with a focus on using interfaces in .NET applications. Polymorphism in .NET can be achieved through virtual or abstract methods, or interfaces.
In all cases, there is a method signature with no implementation at all or an implementation that can be overridden.
The 'contract' of a function (or even a property) is defined but how the method is implemented, the logical guts of the method can be different at runtime, determined by which subclass is instantiated and passed-in to the method or constructor, or set on a property (the act of 'injection').
The official .NET type design guidelines advocate using abstract base classes over interfaces since they have better options for evolving them after shipping, can include convenience overloads and are better able to self-document and communicate correct usage to implementers.
However, care must be taken not to add any logic. The temptation to do so has burned people in the past so many people use interfaces - many other people use interfaces simply because that's what the programmers sitting around them do.
It's also interesting to point out that while DI itself is rarely over-used, using a framework to perform the injection is quite often over-used to the detriment of increased complexity, a chain-reaction can take place where more and more types are needed in the container even though they are never 'switched'.
IoC frameworks should be used sparingly, usually only when you need to swap out objects at runtime, according to the environment or configuration. This usually means switching major component "seams" in the application such as the repository objects used to abstract your data layer.
For me, the real power of an IoC framework is to switch implementation in places where you have no control over creation. For example, in ASP.NET MVC, the creation of the controller class is performed by the ASP.NET framework, so injecting anything is impossible. The ASP.NET framework has some hooks that IoC frameworks can use to 'get in-between' the creation process and perform their magic.
Luke

Categories