Method injection (DI, .NET, IOC) - c#

I am using .NET (MVC5, Web API etc). I understand constructor injection just about (fairly new to using it in anger).
I have a class with a method that has a dependency. I don't want to use constructor injection because then I will be creating the dependent object every time this class is instantiated (and most of the methods don't use this dependent object).
So I thought method injection sounded like it might be the thing. However I can't figure out how to do it (I am using Autofac).
So if my method is
void DoSomething(string x, int y)
and that method needs to use an implementation of IMyService, how do I do this without using the constructor injection?
The only method injection technique I have seen is one where effectively a method is called at instantiation. This doesn't seem to help my case, it still means that all instances create this dependency even if I am going to call a method that doesn't need it.
I'm sure it is something simple but I can't figure it out right now. Could you help me with an example please?
UPDATE
this is the crux of it. I like the idea of Lazy suggested by Jim and will try this. So is method injection as I suspected and if so I don't really understand the point of it - why use it instead of constructor injection?
public class MailService {
// lots of methods that don't need PlayerDataService
public void SendPlayersEmail() {
var service = new PlayerDataService();
var players = service.GetPlayers();
foreach(var player in players) {
SendEmail(player);
}
}
}

I don't want to use constructor injection because then I will be creating the dependent object every time this class is instantiated (and most of the methods don't use this dependent object).
There's the problem. Break that functionality out into a new class.
That is, at least in my experience, the best solution when a method does not fit into the rest of the class (or have dependencies that are not used anywhere else).
You should also consider that object allocation is pretty cheap, you need millions of allocations per second before the performance is hurt (unless you are using Ninject ;))

If the cost of instantiating your object during construction is an issue, you can wrap it in a Lazy<> to avoid unnecessary construction. This will cause your dependency to be constructed on the first call to the lazy's .Value.

Related

In ReactiveUI, how to call GetService for MutableDependencyResolver

I am reading the book You, I and ReactiveUI and my question relates to the source code for the book at https://github.com/kentcb/YouIandReactiveUI. The versions of ReactiveUI and Splat have changed since the code was published and one portion of the code cannot be duplicated in the current versions. I have contacted the author and am still waiting on a response as of this time of posting this question, and so I am submitting this question here.
In App.xaml.cs there is a call to a Registrations.cs class that passes the current mutable dependency resolver:
public App()
{
this.autoSuspendHelper = new AutoSuspendHelper(this);
Registrations.Register(Splat.Locator.CurrentMutable);
}
In the Registrations.cs class, there is a line that takes that IMutableDependencyResolver and calls GetService:
public static void Register(IMutableDependencyResolver container)
{
...
var defaultViewLocator = container.GetService<IViewLocator>();
...
}
I, too, would like to get the IVewLocator service, but IMutableDependencyResolver no longer has a GetService method.
So my question is, how should this code be modified to have the same functionality?
The Splat.Locator.Current is an IReadonlyDependenyResolver and that does have a GetService method. Should that be used instead? I wasn't sure if I should change to using Splat.Locator.Current in case there was a reason that Splat.Locator.CurrentMutable was used and wanted to make sure that if I changed to using Splat.Locator.Current that it would not introduce anything unexpected.
UPDATE:
Just want to add that, armed with the knowledge from DPVreony's answer that it is typically the same class implementing the two interfaces, I was able to implement some later lines in the Registrations.cs class that I needed.
So, further in that class, there are some lines that register constants. These needed the mutable dependency resolver. So you can just pass both the read only and mutable into the Registrations class and use them where needed, as shown below:
public static void Register(IReadonlyDependencyResolver container, IMutableDependencyResolver mutableContainer)
{
...
var defaultViewLocator = container.GetService<IViewLocator>();
...
mutableContainer.RegisterConstant(viewLocator, typeof(IViewLocator));
...
var defaultActivationForViewFetcher = container.GetService<IActivationForViewFetcher>();
...
mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IActivationForViewFetcher));
mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IForcibleActivationForViewFetcher));
}
And then call the method like so:
Registrations.Register(Splat.Locator.Current, Splat.Locator.CurrentMutable);
There was a change in Splat due to how some DI containers behave with registering services (i.e. they keep re-initializing). So get functionality was split off onto the IReadonlyDependenyResolver exposed by Splat.Locator.Current
It was to encourage the mindset of use the MutableLocator to get everything in place and then after that you should only ever need to read using Splat.Locator.Current so you're fine to use it. Typically it's the same class implementing the 2 interfaces, so it's a semantic change to reduce risks of tearing down the locator by mistake.
So in short yes Splat.Locator.Current is for GetService
Hope that all makes sense.

Is there an advantage to using a static method which returns a new instance via a private constructor?

A pattern I occasionally see is like this:
public class JustAnotherClass
{
private JustAnotherClass()
{
// do something
}
static JustAnotherClass GetNewClass()
{
return new JustAnotherClass();
}
}
Why would this ever give an advantage over just having a public constructor?
Why would this ever give an advantage over just having a public constructor?
It's a factory pattern. You have a single point where these instances are made.
The advantage would be that in a future extension you could add logic, like returning a derived class instance. Or to return null under certain conditions. A constructor cannot return null.
Good question. The class you show is a factory (see factory pattern). So 'why use a factory' ... as I said a good question.
For me, I use factories when I need to create instances at run time (many times). Why? Because it makes my code some much easier to test using unit testing. This is one answer to you question and it is irrelevant if you do not unit test (and perhaps TDD) your code. No wrongs or rights here, just a fact.
To answer you question ask 'why use a factory'.
Besides from being for flexible, you need this approach if you want to use parameters in your constructor (at least this behavior) and XML serialization at the same time.
I don't see any advantage of having a static method just to create a new object. It is more or less equvalent to directly call constructor.
it makes code more scaleable which won't be possible with public constructor. Check Henk holterman's answer also.
It can return a derived class.
Sometimes you have different internal implementations of a base class, and the consumer shouldn't know which one he got, since it's an implementation detail.
It has a name.
I often use it instead of overloading the constructor, so it becomes clearer what the meaning of this new instance is.
One example from a recent project of me: I have a class representing an asymmetric key-pair. The constructor is protected and there are two factory methods: FromPrivateKey(byte[]) and GenerateIdentity(). IMO this makes consuming code easier to read.
As it is in your example there's no real advantage. You use a factory method when you want to control when and how instances of your class are created. Some examples:
You want to implement a Singleton, that is always return the same instance;
You want to implement a cache and ensure that new instances are created only when no existing instance is available;
You need to control when instances are created based on external information. For instance you might be mapping the file system and want to ensure that no two instances of your File class exist for the same pathname.

SimpleServiceLocator: Why is automatic constructor injection not supported for singletons?

I've been experimenting with the SimpleServiceLocator, and I like it quite a bit, but there's one thing that I'm really frustrated by--you can't use automatic constructor injection for singletons. To make matters worse, you can't even use automatic constructor injection for its dependencies. You have to create the singleton object, all it's dependencies, all its dependencies dependencies, etc. manually.
Why is SimpleServiceLocator designed this way?
Aren't singletons supposed to be just like regular instances except that, upon the first request for an instance, that instance is stored and reused instead of a new one being created each time? Why does SimpleServiceLocator require an instance to be provided during the registration process rather than just allow the instance to be created and stored on first request?
I get that the point of SimpleServiceLocator is to not have a lot of bells and whistles and be really easy for beginners to use, but it seems like it's just designed incorrectly, and that the method for registering a singleton should be identical to the method for registering a regular instance except that the method name should be RegisterSingle<T>() instead of Register<T>(). Is there a reason for the more complicated (and seemingly less convenient) design I'm just not getting?
Meanwhile, is there another (preferably free) IOC container I can use that let's me register objects in code similarly to the SimpleServiceLocator but does allow automatic contructor injection for singletons (or at least allows automatic constructor injection for the dependencies of the singleton)?
The RegisterSingle<T> method is just a fancy helper method just to make life easier. What you can do with RegisterSingle<T> can also be done with the Register<T> method. The web site gives examples of this. You can register a single instance using the Register<T> method as follows (it uses a closure):
var weapon = new Katana();
container.Register<IWeapon>(() => weapon);
When you look at the lifestyle management examples on the web site, you can see the following example for creating a thread static instance:
[ThreadStatic]
private static IWeapon weapon;
container.Register<IWeapon>(
() => return weapon ?? (weapon = new Katana()));
I think this is the power of simplify, because there is almost nothing you can't do with this pattern. What you are trying to achieve is a bit harder, I must admit this, but nothing really advanced IMO. Here is the code you need to solve your problem:
private static IWeapon weapon;
container.Register<IWeapon>(
() => weapon ?? (weapon = container.GetInstance<Katana>()));
The trick is here to store the instance in a static variable (just as with the thread static), but now you should not create the instance yourself by newing it up, but you delegate the creation to the Simple Service Locator. This works, because –as you know- the SimpleServiceLocator will do automatic constructor injection when a concrete type is requested.
I must admit that it is a shame that we need to do this trickery. It would be nice if the library could actually do this for us. For instance, I can imagine a RegisterSingle<T> overload being added that allows us to do the following:
container.RegisterSingle<IWeapon>(
() => container.GetInstance<Katana>());
Please let me know what you think of such an overload. I'm always interested in feedback to make the library better. This would certainly be a nice feature for the next release.
Update:
Since release 0.14 we can do the following:
container.RegisterSingle<IWeapon, Katana>();
It won't get any easier than this.
Cheers
A typical singleton implementation has a private constructor, so the container cannot "see" it, call it, or detect dependencies.
Perhaps you are referring to the lifetime management features of some IoC containers, where you can configure the container to always return the same single instance of a class.
This is not what singleton means. Although the container returns the same instance, nothing prevents you from instantiating an instance in code using new.
A singleton, on the other hand, can only ever be instantiated once from any source (once per thread in some implementations). It does not expose a public constructor, rather a static method such as:
public class MySingleton
{
// note: not a thread-safe implementation
static MySingleton instance;
static DependencyThing thing;
private MySingleton(DependencyThing thing)
{
MySingleton.thing = thing;
}
public static MySingleton GetMySingleton(DependencyThing thing)
{
if(instance == null) instance = new MySingleton(thing);
return instance;
}
}
As you can see, you can't call new MySingleton() from outside the class itself. To "instantiate" the a MySingleton, you have to call MySingleton.GetMySingleton(thing). This call returns the sole instance or creates and then returns it.
SimpleServiceLocator has no way of knowing how to create this object, or from where to detect its dependencies.
This ability could be added if the API exposed something like
public void Register<T>(Expression<Func<T>> staticFactoryMethod)…
…in which case you could call Register(() => MySingleton.GetMySingleton());, but this would only work without parameters. There would have to be more overloads:
public void Register<T, TParam1>(Expression<Func<TParam1, T>> staticFactoryMethod)…
public void Register<T, TParam1, TParam2>(Expression<Func<TParam1, TParam2, T>> staticFactoryMethod)…
…so that the container would know what dependencies to instantiate and pass to the specified factory method.
All that said, it doesn't really make sense to have dependency injection with a singleton. Each subsequent call to GetMySingleton would have to ignore the arguments or alter the state of the singleton, which is almost certainly a very bad idea.

DAL Design/Load methods with NHibernate

public MyClass(int someUniqueID)
{
using(//Session logic)
{
var databaseVersionOfMyClass = session.CreateCriteria(/*criteria*/)
.UniqueResult<MyClass>();
//Load logic
}
}
The code sample above is my current direction, although I've reached a point where I need a bit of a sanity check.
With NHibernate(I'm green in this area), is it common or best practice to instantiate an object from a database within the class constructor? The alternative I believe, would be to have a static method that returns the object from the database.
I've also come across a relevent question regarding constructors vs factory methods, however I don't believe this implementation fits the factory methodology.
To add an additional question onto the above, if instantiation within the constructor is the way to go, I've always used some sort of Load() method in the past. Either a specific private method that literally matches properties from the returned db object to the new class, or via a generic reflective method that assumes property names will match up. I'm curious if there is another way to "load" an object that I've missed.
I do not like this approach.
IMHO , it is better to implement some kind of repository which retrieves instances of persisted classes for you.
As an alternative, you could also follow the ActiveRecord approach, where you could have a static 'Load' method inside your class, and an instance method 'Save' for instance. (Take a look at Castle ActiveRecord).
But, for me, I prefer the Repository approach.

Linq2Sql, OOP, DependencyInjection problem

I'm still struggling a bit with OOP concepts and dependency injection so bear with me.
I have generated my Linq2Sql model with a User table and now I would like to be able to send a confirmation email to this user so I created a partial class file for my User object and I felt it was natural to add a SendConfirmationEmail() method to the User class. This method will use a MailService to send the actual email and I would like to use dependency injection to pass in the service so I created a constructor overload on the User object like this
public User(IMailService service) : this()
{
_service = service;
}
The SendConfirmationEmail method would look like this
public void SendConfirmationEmail()
{
_service.SendMail(params...);
}
I realize this is a kind of poor mans dependency injection and I hope to switch to a dependency injection framework later as I am getting more grips on this.
The problem for me is that I need to make a reference from my model dll to my service dll which does not seem right and because I am unsure of how nice my linq2sql generated entities plays with Dependency injection frameworks and OOP concepts (I think ninject looks most promising).
I was hoping someone with a bit more experience than me could tell I'm if I am going in the right direction with this. I know I can make it work but I would like to educate my self in doing it in the correct way in the same step.
I personally would change some things in your architecture:
I don't think that SendConfirmationEmail should be a method on your User object. But should be a method on another object with the user as a parameter. (this also better seperates your Dal from the other logic.
Second in this method use something like this:
Services.Get<IMailService>().SendMail(params ...);
You can implement Services as the folowin (just an example):
public class Services
{
protected static Dictionary<Type, object> services = new Dictionary<Type, object>();
private Services()
{
}
static Services()
{
// hard coded implementations...
services.Add(typeof(IMailService), new DefaultMailServiceImplementation());
}
public static T Get<T>() where T : class
{
Type requestedType = typeof(T);
return services[requestedType] as T;
}
}
By using a "Services"-class (or call it what you like) you add an additional layer between the IOC-framework and your code which makes it easy to change IOC-frameworks. Just change the implementation in the Get method to use one. You can also use a hardcoded temporary solution (until you use an IOC-framework) in the static constructor (like I did in the above example).
The problem with that approach is that much of the time the entity is going to come from the LINQ-to-SQL back-end, and so isn't going to use your constructor (LINQ-to-SQL creates objects in its own way; you cannot force LINQ-to-SQL to use your constructor) - so this would only be useful for the (few) objects you create yourself. Data-binding (etc) will also commonly use the parameterless constructor by default.
I wonder if this wouldn't work better as a utility method that accepts the service, or obtains the service itself via a factory / singleton.
I think you're ok doing this, but you might want to do two additional things to protect yourself from future cross-layer dependency problems:
Create an interface for your User
object. You should do this because
not doing so will mean that
everything that consumes this
business object will have to
reference the LINQ dlls
unnecessarily.
Move your dependency injection from
the constructor into a property.
You do this because constructor
injection tends to limit your
ability to dynamically create your
object. Doing this, though poses a
problem, since you would have to
implement a lot of null checking
code for _service. You can fix this
by creating an "empty"
implementation of IMailService and
make it the default value for
_service.

Categories