What does kernel.Bind<SomeType>().ToSelf() do? - inversion-of-control

I understand the following Ninject registration:
kernel.Bind<ISomeType>().To<SomeTypeImplementation>();
which tells Ninect to fulfill requests for ISomeType by using SomeTypeImplementation.
However I'm not sure what the following is good for.
kernel.Bind<ApplicationDbContext>().ToSelf();
Which was suggested that I use from this question:
What ninject binding should I use?

It makes ApplicationDbContext "self-bindable". If you don't have an interface to bind to, you can bind to the class itself. It's more useful if you add a scope to the call such as:
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
Any time it sees the ApplicationDbContext that needs to be injected, it will reuse the same object as long as it is in the same HTTP request.
The default scope is transient, which means that any time a class requests ApplicationDbContext it will create a new instance of it. This can be problematic if you have two classes that both need to use the context in the same transaction. That is why you will often see it done with InRequestScope().

By self-binding a type, you enable that type for the following:
Lifecycle Management by the container.
Enable the container to inject dependencies into other types that depend on the self-bound type, and inject dependencies of this type into its instances likewise.
Very useful if you just have one single implementation or you don't need to use abstractions for some reason.

Related

Using Zenject to inject an implementation with interfaces

I'm trying to use Zenject in Unity. I have an interface and several implementations of it.
I want to inject with ID but also that the implementation will have the tick interface since it's not a MonoBehaviour.
So I have an IAttacker interface and a MeleeAttackImpl implementation.
Container.Bind<IAttacker>().WithId(AttackerTypeEnum.MELEEE).To<MeleeAttackImpl>().AsTransient();
I want to add
Container.BindInterfacesTo<MeleeAttackImpl>().AsTransient();
But it creates 2 different objects instead of instances that have the Tick interface and bind them to IAttacker.
If you want to bind an interface to a determined implementation, why do you use two bindings?
If you want only one instance of the object I would try:
Container.BindInterfacesAndSelfTo<MeleeAttackImpl>().AsSingle();
or:
Container.Bind<IAttacker>().To<MeleeAttackImpl>().AsSingle();
As Single() In the case you need the same instance provided from the container along the app (like a singleton).
From the documentation:
"AsTransient - Will not re-use the instance at all. Every time ContractType is requested, the DiContainer will execute the given construction method again."
Many times intance is created in the binding itself. So maybe from the two binding two instances are created, one from each binding.
In case you need to create instances dynamically with all their dependencies resolved, what you need a is Factory.

How inject dependency in custom TelemetryInitializer?

We are using Autofac 4 for DI and I started experimenting with AI a short while ago. Now I created a IdentityTelemetryInitializer class which needs and IIdentityProvider to be able to get the ID of the current authorized user and set it add it to the context. I cannot find a way in which to inject dependencies into a TelemetryInitializer. If I define a contructor that takes an IIdentityProvider, the custom initializer is skipped altogether.
Any ideas are welcome. I was thinking of having the user ID also set as the Thread Principal so that we can access it this way, but I was hoping I could use DI for this?
You cannot inject dependencies using a constructor as the initializer initialized internally using the default (empty) constructor. When you explicitly defined a new ctor you've actually 'removed' the default one, thus the initializer was skipped altogether, as you've mentioned.
Therefore, the only way is to resolve the dependencies during the 'Initialize' method, after registering them on application startup.
ctx.RegisterType<MyService>().As<IService>().AsSelf(); // on application startup
ctx.Resolve<IService>(); // during initializer 'Initialize' method
You might look at the question I asked here
How to have "Request" events with authenticated user id ?
because I had managed to have the TelemetryInitializer working, passing user id via the HttpContext as suggested by #yonisha.
Off course it's not as lean as what you try to achieve.
The Telemetry Initializer is called each time you instanciate a Telemetry class, so really depending of how you manage them. Btw I am looking for good advice/best pratice on that : for the moment I have one private instance on each Controller that need to track something, but that does not smell good due to lifetime of Controller.

IoC (StructureMap) Best Practice

By my (likely meager) understanding, doing this in the middle of a method in your controller / presenter is considered bad practice, since it creates a dependency between StructureMap and your presenter:
void Override() {
ICommentForOverrideGetter comm = StructureMap.ObjectFactory.GetInstance<ICommentForOverrideGetter>();
since this dependancy should be injected into the presenter via the constructor, with your IoC container wiring it up. In this case though my code needs a fresh copy of ICommentForOverrideGetter every time this method runs. Is this an exception to the above best practice, or a case where I should re-think my architecture?
It is said that there is no problem in computer science which cannot be solved by one more level of indirection:
If you just don't want the dependency in your presenter, inject a factory interface, the real implementation could do new CommentForOverrideGetter or whatever.
Edit:
"I have no problem ignoring best practices when I think the complexity/benefit ratio is too high": Neither do I, but as I said in the comments, I don't like hard dependencies on IoC containers in code I want to unit test and presenters are such a case.
Depending on what your ICommentForOverrideGetter does, you could also use a simple CommentForOverrideGetter.CreateNew() but as you require a fresh instance per call, I'd suspect at least some kind of logic associated with the creation? Or is it a stateful "service"?
If you insist on doing service location in your method, you should at least inject the container into your controller, so that you can eliminate the static method call. Add a constructor parameter of type StructureMap.IContainer and store it in a field variable. StructureMap will inject the proper container. You can then call GetInstance() on that container, instead of ObjectFactory.

ServiceContainer, IoC, and disposable objects

I have a question, and I'm going to tag this subjective since that's what I think it evolves into, more of a discussion. I'm hoping for some good ideas or some thought-provokers. I apologize for the long-winded question but you need to know the context.
The question is basically:
How do you deal with concrete types in relation to IoC containers? Specifically, who is responsible for disposing them, if they require disposal, and how does that knowledge get propagated out to the calling code?
Do you require them to be IDisposable? If not, is that code future-proof, or is the rule that you cannot use disposable objects? If you enforce IDisposable-requirements on interfaces and concrete types to be future-proof, whose responsibility is objects injected as part of constructor calls?
Edit: I accepted the answer by #Chris Ballard since it's the closest one to the approach we ended up with.
Basically, we always return a type that looks like this:
public interface IService<T> : IDisposable
where T: class
{
T Instance { get; }
Boolean Success { get; }
String FailureMessage { get; } // in case Success=false
}
We then return an object implementing this interface back from both .Resolve and .TryResolve, so that what we get in the calling code is always the same type.
Now, the object implementing this interface, IService<T> is IDisposable, and should always be disposed of. It's not up to the programmer that resolves a service to decide whether the IService<T> object should be disposed or not.
However, and this is the crucial part, whether the service instance should be disposed or not, that knowledge is baked into the object implementing IService<T>, so if it's a factory-scoped service (ie. each call to Resolve ends up with a new service instance), then the service instance will be disposed when the IService<T> object is disposed.
This also made it possible to support other special scopes, like pooling. We can now say that we want minimum 2 service instances, maximum 15, and typically 5, which means that each call to .Resolve will either retrieve a service instance from a pool of available objects, or construct a new one. And then, when the IService<T> object that holds the pooled service is disposed of, the service instance is released back into its pool.
Sure, this made all code look like this:
using (var service = ServiceContainer.Global.Resolve<ISomeService>())
{
service.Instance.DoSomething();
}
but it's a clean approach, and it has the same syntax regardless of the type of service or concrete object in use, so we chose that as an acceptable solution.
Original question follows, for posterity
Long-winded question comes here:
We have a IoC container that we use, and recently we discovered what amounts to a problem.
In non-IoC code, when we wanted to use, say, a file, we used a class like this:
using (Stream stream = new FileStream(...))
{
...
}
There was no question as to whether this class was something that held a limited resource or not, since we knew that files had to be closed, and the class itself implemented IDisposable. The rule is simply that every class we construct an object of, that implements IDisposable, has to be disposed of. No questions asked. It's not up to the user of this class to decide if calling Dispose is optional or not.
Ok, so on to the first step towards the IoC container. Let's assume we don't want the code to talk directly to the file, but instead go through one layer of indirection. Let's call this class a BinaryDataProvider for this example. Internally, the class is using a stream, which is still a disposable object, so the above code would be changed to:
using (BinaryDataProvider provider = new BinaryDataProvider(...))
{
...
}
This doesn't change much. The knowledge that the class implements IDisposable is still here, no questions asked, we need to call Dispose.
But, let's assume that we have classes that provide data that right now doesn't use any such limited resources.
The above code could then be written as:
BinaryDataProvider provider = new BinaryDataProvider();
...
OK, so far so good, but here comes the meat of the question. Let's assume we want to use an IoC container to inject this provider instead of depending on a specific concrete type.
The code would then be:
IBinaryDataProvider provider =
ServiceContainer.Global.Resolve<IBinaryDataProvider>();
...
Note that I assume there is an independent interface available that we can access the object through.
With the above change, what if we later on want to use an object that really should be disposed of? None of the existing code that resolves that interface is written to dispose of the object, so what now?
The way we see it, we have to pick one solution:
Implement runtime checking that checks that if a concrete type that is being registered implements IDisposable, require that the interface it is exposed through also implements IDisposable. This is not a good solution
Enfore a constraint on the interfaces being used, they must always inherit from IDisposable, in order to be future-proof
Enforce runtime that no concrete types can be IDisposable, since this is specifically not handled by the code using the IoC container
Just leave it up to the programmer to check if the object implements IDisposable and "do the right thing"?
Are there others?
Also, what about injecting objects in constructors? Our container, and some of the other containers we've looked into, is capable of injecting a fresh object into a parameter to a constructor of a concrete type. For instance, if our BinaryDataProvider need an object that implements the ILogging interface, if we enforce IDispose-"ability" on these objects, whose responsibility is it to dispose of the logging object?
What do you think? I want opinions, good and bad.
One option might be to go with a factory pattern, so that the objects created directly by the IoC container never need to be disposed themselves, eg
IBinaryDataProviderFactory factory =
ServiceContainer.Global.Resolve<IBinaryDataProviderFactory>();
using(IBinaryDataProvider provider = factory.CreateProvider())
{
...
}
Downside is added complexity, but it does mean that the container never creates anything which the developer is supposed to dispose of - it is always explicit code which does this.
If you really want to make it obvious, the factory method could be named something like CreateDisposableProvider().
(Disclaimer: I'm answering this based on java stuff. Although I program C# I haven't proxied anything in C# but I know it's possible. Sorry about the java terminology)
You could let the IoC framework inspect the object being constructed to see if it supports
IDisposable. If not, you could use a dynamic proxy to wrap the actual object that the IoC framework provides to the client code. This dynamic proxy could implement IDisposable, so that you'd always deliver a IDisposable to the client. As long as you're working with interfaces that should be fairly simple ?
Then you'd just have the problem of communicating to the developer when the object is an IDisposable. I'm not really sure how this'd be done in a nice manner.
You actually came up with a very dirty solution: your IService contract violates the SRP, wich is a big no-no.
What I recommend is to distinguish so-called "singleton" services from so-called "prototype" services. Lifetime of "singleton" ones is managed by the container, which may query at runtime whether a particular instance implements IDisposable and invoke Dispose() on shutdown if so.
Managing prototypes, on the other hand, is totally the responsibility of the calling code.

Is there any reason to not use my IoC as a general Settings Repository?

Suppose that the ApplicationSettings class is a general repository of settings that apply to my application such as TimeoutPeriod, DefaultUnitOfMeasure, HistoryWindowSize, etc... And let's say MyClass makes use of one of those settings - DefaultUnitOfMeasure.
My reading of proper use of Inversion of Control Containers - and please correct me if I'm wrong on this - is that you define the dependencies of a class in its constructor:
public class MyClass {
public MyClass(IDataSource ds, UnitOfMeasure default_uom) {...}
}
and then call instantiate your class with something like
var mc = IoC.Container.Resolve<MyClass>();
Where IDataSource has been assigned a concrete implementation and default_uom has been wired up to instantiate from the ApplicationSettings.DefaultUnitOfMeasure property. I've got to wonder however, if all these hoops are really that necessary to jump through. What trouble am I setting myself up for should I do
public class MyClass {
public MyClass(IDataSource ds) {
UnitOfMeasure duom = IoC.Container.Resolve<UnitOfMeasure>("default_uom");
}
}
Yes, many of my classes end up with a dependency on IoC.Container but that is a dependency that most of my classes will have anyways. It seems like I maybe should make full use of it as long as the classes are coupled. Please Agile gurus, tell me where I'm wrong.
IoC.Container.Resolve("default_uom");
I see this as a classic anti-pattern, where you are using the IoC container as a service locater - the key issues that result are:
Your application no longer fails-fast if your container is misconfigured (you'll only know about it the first time it tries to resolve that particular service in code, which might not occur except for a specific set of logic/circumstances).
Harder to test - not impossible of course, but you either have to create a real (and semi-configured) instance of the windsor container for your tests or inject the singleton with a mock of IWindsorContainer - this adds a lot of friction to testing, compared to just being able to pass the mock/stub services directly into your class under test via constructors/properties.
Harder to maintain this kind of application (configuration isn't centralized in one location)
Violates a number of other software development principles (DRY, SOC etc.)
The concerning part of your original statement is the implication that most of your classes will have a dependency on your IoC singleton - if they're getting all the services injected in via constructors/dependencies then having some tight coupling to IoC should be the exception to the rule - In general the only time I take a dependency on the container is when I'm doing something tricky i.e. trying to avoid a circular dependency problems, or wish to create components at run-time for some reason, and even then I can often avoid taking a dependency on anything more then a generic IServiceProvider interface, allowing me to swap in a home-bake IoC or service locater implementation if I need to reuse the components in an environment outside of the original project.
I usually don't have many classes depending on my IoC container. I usually try to wrap the IoC stuff in a facade object that I inject into other classes, usually most of my IoC injection is done only in the higher layers of my application though.
If you do things your way you can't test MyClass without creating a IoC configuration for your tests. This will make your tests harder to maintain.
Another problem is that you're going to have powerusers of your software who want to change the configuration editing your IoC config files. This is something I'd want to avoid. You could split up your IoC config into a normal config file and the IoC specific stuff. But then you could just as well use the normal .Net config functionality to read the configuration.
Yes, many of my classes end up with a dependency on IoC.Container but that is a dependency that most of my classes will have anyways.
I think this is the crux of the issue. If in fact most of your classes are coupled to the IoC container itself chances are you need to rethink your design.
Generally speaking your app should only refer to the container class directly once during the bootstrapping. After you have that first hook into the container the rest of the object graph should be entirely managed by the container and all of those objects should be oblivious to the fact that they were created by an IoC container.
To comment on your specific example:
public class MyClass {
public MyClass(IDataSource ds) {
UnitOfMeasure duom = IoC.Container.Resolve<UnitOfMeasure>("default_uom");
}
}
This makes it harder to re-use your class. More specifically it makes it harder to instantiate your class outside of the narrow usage pattern you are confining it to. One of the most common places this will manifest itself is when trying to test your class. It's much easier to test that class if the UnitOfMeasure can be passed to the constructor directly.
Also, your choice of name for the UOM instance ("default_uom") implies that the value could be overridden, depending on the usage of the class. In that case, you would not want to "hard-code" the value in the constructor like that.
Using the constructor injection pattern does not make your class dependent on the IoC, just the opposite it gives clients the option to use the IoC or not.