I have two abstracts classes, 'ValidationsWithStorage' inherits 'Validations'
public abstract class Validations {
// methods..
}
public abstract class ValidationsWithStorage : Validations {
// ...
}
I also have a class:
public abstract class TestsValidations : T
T should be depend on the environment variable:
Environment.GetEnvironmentVariable("useStorage")
If this variable is null I want that T will be Validations.
Else, I want that T will be ValidationsWithStorage.
What is the best way to do it?
Thanks
I am not sure you can do this with inheritance. This is not the logic of inheritance. It will be better if you use something like factory pattern and change your current deisgn.
May be you can do something like this. I didn't test but i think it will be easier like this:
public interface Validations
{
void ValidationsStuff();
}
public class ValidationsWithStorage : Validations
{
public void ValidationsStuff()
{
//do something
}
}
public class TestsValidations : Validations
{
public void ValidationsStuff()
{
//do something
}
}
public class ValidationsFactory
{
public Validations geValidationsComponent(string useStorage)
{
if (string.IsNullOrEmpty(useStorage))
return new ValidationsWithStorage();
else
return new TestsValidations();
}
}
I don't think you can do what you want to do in the way you do it.
Why not let your class TestValidations take a parameter in its constructor of either type Validations or ValidationsWithStorage. If they both follow the same interface, your TestsValidations class wouldn't need to know (or care) which of the two it's working with.
So basically:
Create an interface for your Validations and ValidationsWithStorage class
Check your environment variable
Pass the correct class into the TestsValidation constructor according to the environment variable
Does that help?
You can do that using conditional compilation:
public abstract class TestsValidations
#if USESTORAGE
: ValidationsWithStorage
#else
: Validations
#endif
{
}
You can set it in project configuration or by passing additional parameters to msbuild: /p:DefineConstants="USESTORAGE"
I don't think this is good design, but it is doable.
If you want to work with inheritance I think your problem will be solved if you use the Generic Constraints
What not to do:
I don't recommend conditionally changing the definition of a class. There are weird, one-off reasons to do that, but we rarely encounter them and shouldn't make them a normal part of how we write code.
I also don't recommend a factory. A factory implies that you're making a decision at runtime, in production, whether to use a "real" class or a test class. A factory only makes sense if some data available only at runtime determines which implementation you want to use. For example, if you want to validate an address, you might use its country to determine whether to us a US validator, Canadian validator, etc, like this:
var validator = _validatorFactory.GetValidator(address.Country);
Also, that means that the "test" class would be referenced from your production code. That's undesirable and a little strange.
What to do:
If you aren't making such a decision at runtime then this should be determined in the composition root - that is, in the part of our application that determines, at startup, which classes we're going to use.
To start with, you need an abstraction. This is most often an interface, like this:
public interface IValidator
{
ValidationResult Validate(Something value);
}
The class that needs the validation would look like this:
public class ClassThatNeedsValidation
{
private readonly IValidator _validator;
public ClassThatNeedsValidation(IValidator validator)
{
_validator = validator;
}
// now the method that needs to use validation can
// use _validator.
}
That's dependency injection. ClassThatNeedsValidation isn't responsible for creating an instance of a validator. That would force it to "know" about the implementation of IValidator. Instead, it expects to have an IValidator provided to it. (In other words its dependency - the thing it needs - is injected into it.)
Now, if you're creating an instance of ClassThatNeedsValidation, it might look like this:
var foo = new ClassThatNeedsValidation(new ValidationWithStorage());
Then, in your unit test project, you might have a test implementation of IValidator. (You can also use a framework like Moq, but I'm with you - sometimes I prefer to write a test double - a test class that implements the interface.)
So in a unit test, you might write this:
var foo = new ClassThatNeedsValidation(new TestValidator());
This also means that TestValidator can be in your test project, not mixed with your production code.
How to make it easier:
In this example:
var foo = new ClassThatNeedsValidation(new ValidationWithStorage());
You can see how this might get messy. What if ValidationWithStorage has its own dependencies? Then you might have to start writing code like this:
var foo = new ClassThatNeedsValidation(
new ValidationWithStorage(
connectionString,
new SomethingElse(
new Whatever())));
That's not fun. That's why we often use an IoC container, a.k.a dependency injection container.
This is familiar if we use ASP.NET Core, although it's important to know that we don't have to use ASP.NET Core to do this. We can add Microsoft.Extensions.DependencyInjection, Autofac, Windsor, or others to a project.
Explaining this is somewhat beyond the scope of this answer, and it might be more than what you need right now. But it enables us to write code that looks like this:
services.AddSingleton<IValidator, ValidationWithStorage>();
services.AddSingleton<Whatever>();
services.AddSingleton<ISomethingElse, SomethingElse>();
services.AddSingleton<ClassThatNeedsValidation>();
Now, if the container needs to create an instance of ClassThatNeedsValidation, it will look at the constructor, figure out what dependencies it needs, and create them. If those classes have dependencies it creates them too, and so on.
This takes a minute or several or some reading/trying if it's a new concept, but trust me, it makes writing code and unit tests much easier. (Unless we do it wrong, then it makes everything harder, but that's true of everything.)
What if, for some reason, you wanted to use a different implementation of IValidator in a different environment? Because the code above is executed once, at startup, that's easy:
if(someVariable = false)
services.AddSingleton<IValidator, OtherValidator>();
else
services.AddSingleton<IValidator, ValidationWithStorage>();
You're making the decision, but you're making it once. A class that depends on IValidator doesn't need to know about this decision. It doesn't need to ask which environment it's in. If we go down that route, we'll end up with stuff like that polluting all of our classes. It will also make our unit tests much more difficult to write and understand. Making decisions like this at startup - the composition root - eliminates all of that messiness.
Related
I am starting to apply SOLID principles, and am finding them slightly contradictory. My issue is as follows:
My understanding of dependency inversion principle is that classes should depend on abstractions. In practice this means classes should be derived from interfaces. All fine so far.
Next my understanding of the open/closed principle is that after a certain cut off point, you should not alter the contents of a class, but should extend and override. This makes sense so far to me.
So given the above, I would end up with something like this:
public interface IAbstraction
{
string method1(int example);
}
public Class Abstraction : IAbstraction
{
public virtual string method1(int example)
{
return example.toString();
}
}
and then at time T, method1 now needs to add " ExtraInfo" onto its returned value. Rather than altering the current implementation, I would create a new class that extends Abstraction and make it do what I needed, as follows.
public Class AbstractionV2 : Abstraction
{
public override string method1(int example)
{
return example.toString() + " ExtraInfo";
}
}
And I can see the reason for doing this is that only the code I want to call this updated method will call it, and the rest of the code will call the old method.
All makes sense to me - and I assume my understanding is correct??
However, I am also using dependency injection (simple injector), so my implementations are never through a concrete class, but instead are through my DI configuration, as follows:
container.Register<IAbstraction, Abstraction>();
The issue here is that under this setup, I can either update my DI config to be:
container.Register<IAbstraction, AbstractionV2>();
In which case all instance will now call the new method, meaning I have failed to achieve not changing the original method.
OR
I create a new interface IAbstractionV2 and implement the updated functionality there - meaning duplication of the interface declaration.
I cannot see any way around this - which leads me to wonder if dependency injection and SOLID are compatible? Or am I missing something here?
TL;DR
When we say that code is "available for extension" that doesn't automatically mean that we inherit from it or add new methods to existing interfaces. Inheritance is only one way to "extend" behavior.
When we apply the Dependency Inversion Principle we don't depend directly on other concrete classes, so we don't need to change those implementations if we need them to do something different. And classes that depend on abstractions are extensible because substituting implementations of abstractions gets new behavior from existing classes without modifying them.
(I'm half inclined to delete the rest because it says the same thing in lots more words.)
Examining this sentence may help to shed some light on the question:
and then at time T, method1 now needs to add " ExtraInfo" onto its returned value.
This may sound like it's splitting hairs, but a method never needs to return anything. Methods aren't like people who have something to say and need to say it. The "need" rests with the caller of the method. The caller needs what the method returns.
If the caller was passing int example and receiving example.ToString(), but now it needs to receive example.ToString() + " ExtraInfo", then it is the need of the caller that has changed, not the need of the method being called.
If the need of the caller has changed, does it follow that the needs of all callers have changed? If you change what the method returns to meet the needs of one caller, other callers might be adversely affected. That's why you might create something new that meets the need of one particular caller while leaving the existing method or class unchanged. In that sense the existing code is "closed" while at the same time its behavior is open to extension.
Also, extending existing code doesn't necessarily mean modifying a class, adding a method to an interface, or inheriting. It just means that it incorporates the existing code while providing something extra.
Let's go back to the class you started with.
public Class Abstraction : IAbstraction
{
public virtual string method1(int example)
{
return example.toString();
}
}
Now you have a need for a class that includes the functionality of this class but does something different. It could look like this. (In this example it looks like overkill, but in real-world example it wouldn't.)
public class SomethingDifferent : IAbstraction
{
private readonly IAbstraction _inner;
public SomethingDifferent(IAbstraction inner)
{
_inner = inner;
}
public string method1(int example)
{
return _inner.method1 + " ExtraInfo";
}
}
In this case the new class happens to implement the same interface, so now you've got two implementations of the same interface. But it doesn't need to. It could be this:
public class SomethingDifferent
{
private readonly IAbstraction _inner;
public SomethingDifferent(IAbstraction inner)
{
_inner = inner;
}
public string DoMyOwnThing(int example)
{
return _inner.method1 + " ExtraInfo";
}
}
You could also "extend" the behavior of the original class through inheritance:
public Class AbstractionTwo : Abstraction
{
public overrride string method1(int example)
{
return base.method1(example) + " ExtraInfo";
}
}
All of these examples extend existing code without modifying it. In practice at times it may be beneficial to add existing properties and methods to new classes, but even then we'd like to avoid modifying the parts that are already doing their jobs. And if we're writing simple classes with single responsibilities then we're less likely to find ourselves throwing the kitchen sink into an existing class.
What does that have to do with the Dependency Inversion Principle, or depending on abstractions? Nothing directly, but applying the Dependency Inversion Principle can help us to apply the Open/Closed Principle.
Where practical, the abstractions that our classes depend on should be designed for the use of those classes. We're not just taking whatever interface someone else has created and sticking it into our central classes. We're designing the interface that meets our needs and then adapting other classes to fulfill those needs.
For example, suppose Abstraction and IAbstraction are in your class library, I happen to need something that formats numbers a certain way, and your class looks like it does what I need. I'm not just going to inject IAbstraction into my class. I'm going to write an interface that does what I want:
public interface IFormatsNumbersTheWayIWant
{
string FormatNumber(int number);
}
Then I'm going to write an implementation of that interface that uses your class, like:
public class YourAbstractionNumberFormatter : IFormatsNumbersTheWayIWant
{
public string FormatNumber(int number)
{
return new Abstraction().method1 + " my string";
}
}
(Or it could depend on IAbstraction using constructor injection, whatever.)
If I wasn't applying the Dependency Inversion principle and I depended directly on Abstraction then I'd have to figure out how to change your class to do what
I need. But because I'm depending on an abstraction that I created to meet my needs, automatically I'm thinking of how to incorporate the behavior of your class, not change it. And once I do that, I obviously wouldn't want the behavior of your class to change unexpectedly.
I could also depend on your interface - IAbstraction - and create my own implementation. But creating my own also helps me adhere to the Interface Segregation Principle. The interface I depend on was created for me, so it won't have anything I don't need. Yours might have other stuff I don't need, or you could add more in later.
Realistically we're at times just going to use abstractions that were given to us, like IDataReader. But hopefully that's later when we're writing specific implementation details. When it comes to the primary behaviors of the application (if you're doing DDD, the "domain") it's better to define the interfaces our classes will depend on and then adapt outside classes to them.
Finally, classes that depend on abstractions are also more extensible because we can substitute their dependencies - in effect altering (extending) their behavior without any change to the classes themselves. We can extend them instead of modifying them.
Addressing the exact problem you mentioned:
You have classes that depend on IAbstraction and you've registered an implementation with the container:
container.Register<IAbstraction, Abstraction>();
But you're concerned that if you change it to this:
container.Register<IAbstraction, AbstractionV2>();
then every class that depends on IAbstraction will get AbstractionV2.
You shouldn't need to choose one or the other. Most DI containers provide ways that you can register more than one implementation for the same interface, and then specify which classes get which implementations. In your scenario where only one class needs the new implementation of IAbstraction you might make the existing implementation the default, and then just specify that one particular class gets a different implementation.
I couldn't find an easy way to do this with SimpleInjector. Here's an example using Windsor:
var container = new WindsorContainer();
container.Register(
Component.For<ISaysHello, SaysHelloInSpanish>().IsDefault(),
Component.For<ISaysHello, SaysHelloInEnglish>().Named("English"),
Component.For<ISaysSomething, SaysSomething>()
.DependsOn(Dependency.OnComponent(typeof(ISaysHello),"English")));
Every class that depends on ISaysHello will get SaysHelloInSpanish except for SaysSomething. That one class gets SaysHelloInEnglish.
UPDATE:
The Simple Injector equivalent is the following:
var container = new Container();
container.Register<ISaysSomething, SaysSomething>();
container.RegisterConditional<ISayHello, SaysHelloInEnglish>(
c => c.Consumer.ImplementationType == typeof(SaysSomething));
container.RegisterConditional<ISayHello, SaysHelloInSpanish>(
c => c.Consumer.ImplementationType != typeof(SaysSomething))
Modules become closed to modification once they are referenced by other modules. What becomes closed is the public API, the interface. Behavior can be changed via polymorphic substitution (implementing the interface in a new class and injecting it). Your IoC container can inject this new implementation. This ability to polymorphically substitute is the 'Open to extension' part. So, DIP and Open/Closed work together nicely.
See Wikipedia:"During the 1990s, the open/closed principle became popularly redefined to refer to the use of abstracted interfaces..."
This one is a bit complicated, so please read everything through. I'm working on some code that implements the MVVM Pattern for WPF. I have a XAML Markup extension that looks for a specific property on the datacontext. (It's a long and fun story, but out of scope) My view model will be set as the Dataconext on the view.
Here's an example of how I have implemented my BaseViewmodel...
public class ViewModelBase : IViewModelBase
{
protected CommandManagerHelper _commandManagerHelper;
//todo find a way of eliminating the need for this constructor
public OrionViewModelBase(CommandManagerHelper commandManagerHelper)
{
_commandManagerHelper = commandManagerHelper;
}
private IExampleService _exampleService;
public IExampleService ExampleService
{
get
{
if (_exampleService == null)
{
_exampleService = _commandManagerHelper.GetExampleService();
}
return _exampleService;
}
}
}
What's going on there is that I'm effectively lazy loading the _exampleService. I'm sure it's possible to use Lazy, but I've not got round to implementing that just yet.
My Xaml Markup will be looking for and making use of my the ExampleService it could also be used by code within the view model. It's going to be used all over the application.
A point to note is that my application will have only one instance of the ExampleServer that will be passed around, calling GetExampleService from anywhere in the application will return the same instance of the object. There will only be one instance of the ExampleService object, although it is not coded as a singleton.
Here is an example of how I am inheriting from my ViewModelBase...
internal class ReportingViewmodel : ViewModelBase
{
private readonly IReportingRepository _reportingRepository;
public ReportingViewmodel(CommandManagerHelper commandManagerHelper, IReportingRepository reportingRepository) : base(commandManagerHelper)
{
_reportingRepository = reportingRepository;
}
}
This code works and works great. However, having to type ": base(commandManagerHelper)" every time that I implement a new inherited member of the ViewModelBase is prone to mistakes. I'm likely to have 100's of these implementations and each one needs to be right.
What I'm wondering is.... is there a way of implementing the same behaviour respecting the SOLID principles and not having to call the base constructor every time I implement an instance of the ViewModelBase?
i.e. I'd like the ReportingViewModel to look like this
internal class ReportingViewmodel : ViewModelBase
{
private readonly IReportingRepository _reportingRepository;
public ReportingViewmodel(IReportingRepository reportingRepository)
{
_reportingRepository = reportingRepository;
}
}
but still have the ExampleService populated correctly.
I'm currently considering using the Service locator pattern for this, I'm also considering using a Singleton and I'm open to other better solutions.
The reason that I'm asking the question rather than diving in with code is that I know that the Singleton is generally an anti-pattern, to me it signifies that something else is wrong in the code.
I've just read an article on IoC and it's slating the Service locator pattern here's the article http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container.
You can't get out of calling the base constructor.
It doesn't really matter that IExampleService is only instantiated once and shared. Your ViewModelBase doesn't (and shouldn't) "know" that. All it needs to know is that whatever is injected implements that interface.
That's one of the big benefits, because when you unit test classes you can inject a mocked version of that interface. If classes depended on a static reference to something buried within a base class then it wouldn't be possible to replace it with a mock for testing.
I use ReSharper. (Am I allowed to say that? I don't mean to advertise.) Among many other things it generates those base constructors for you. I'm sure at some point that's got to get built in to Visual Studio.
I have a C# class which instantiates on its own a NetworkCommunicator class. I'd like to mock out the NetworkCommunicator class for my unit test, and replace it with a pretty simple stub.
But the NetworkCommunicator is never passed as a parameter. It's created by the class being tested.
In Ruby, this is easy to mock out. In Java, this is why you need Dependency Injection, which is too heavy for this project. Is there a simple way to mock this out in C#, perhaps using Moq or something similar?
You mentioned that DI is too heavyweight for this project, why not try some Truck Driver's DI, thus:
public interface IDependency
{
void DoSomeStuff();
}
public class ClassUnderTest
{
private IDependency _dependency;
public ClassUnderTest(IDependency dependency)
{
_dependency = dependency;
}
public ClassUnderTest() : this(new Dependency())
{}
public void ImportantStuff()
{
_dependency.DoSomeStuff();
}
}
Using this constructor chaining technique, you can now mock the IDependency all you want, without worrying about hooking up DI or IoC.
Create a "TestClass" that inherits from your class under test.
Override that parameter with a mocked instance
Create a property on the class under test that returns the new instance
public class ClassUnderTest {
public string MethodYouAreTesting(int someInput) {
var networkCommunicator = GetNetworkCommunicator();
// Do some stuff that I might want to test
return "foo";
}
public virtual NetworkCommunicator GetNetworkCommunicator {
return new NetworkCommunicator();
}
}
[TestFixture]
public class ClassUnderTestTests {
public void GivenSomeCondition_MethodYouAreTesting_ReturnsFooString() {
var classToTest = new TestClassUnderTest();
var result = classToTest.MethodYouAreTesting(1);
Assert.That(result, Is.EqualTo("foo");
}
}
public class TestClassUnderTest : ClassUnderTest {
public override GetNetworkCommunicator {
return MockedNetworkCommunicator;
}
}
I read of this technique this in the "Art of Unit Testing" and use it frequently when refactoring to full DI doesn't make sense or when the class I'm testing isn't something I can change.
Hope this helps.
You should refactor your code and pass dependencies in. You can also use typemock as easier to use alternative to fakes in Visual Studio 2012.
There's the built-in Fakes system, pretty well described at http://msdn.microsoft.com/en-us/library/hh549175.aspx
If that is too heavy-weight for your use case you might find the PrivateObject class more useful.
I have a C# class which instantiates on its own a NetworkCommunicator class.
As you noticed, this is a show stopper in C# when you want to mock this thing out. Solution is simple, and depends on context/purpose of the instantiated class:
inject it as a dependency if it's reusable component
provide it via factory if it's something that should be created every time when demand comes in
Either way, you'll need DI (factory from the second example is naturally injected too).
In Java, this is why you need Dependency Injection, which is too heavy for this project.
Is dependency injection too heavy? DI is design pattern, it's only too heavy when used when it's not really needed. Your question clearly shows you need it. Perhaps you meant that DI container is too heavy for your project? This might be true, as depending on project's complexity, you should choose appropriate way to apply DI.
I'd like to raise one more point to be aware of when applying solution like the one proposed in Greg Smith's answer. Essentially, your API ends up with constructors:
public TestedClass() : this(new Dependency()) ...
public TestedClass(IDependency) ...
As appealing as it might be at first glance, when long-term perspective is taken into account, several issues start to emerge:
does TestedClass must have IDependency or can it do fine without it?
what default (parameterless constructor) defaults to (implementation detail-level knowledge is required to use it properly)?
it creates tightly coupled components (TestedClass assembly will possibly have to reference other assembly - Dependency's assembly, even though it might not be relevant to it anyhow)
This is an anti-pattern going under different names, e.g. Bastard Injection. Of course, some of those problems might be mitigated (like making constructor protected/internal or having default implementation in the same assembly), but the anti-pattern and its long-term consequences remain. Also note that it's by no means more simple, faster or less code than regular DI.
You'll have to ask yourself what's less heavy - applying proper DI, or going you ways around with anti-patterns and/or 3rd party frameworks (MS Fakes).
Disclaimer: I would love to be using dependency injection on this
project and have a loosely coupled interface-based design across the board, but use of dependency-injection has been shot down in this project. Also SOLID design principles (and design patterns in general) are something foreign where I work and I'm new to many of them myself. So take that into
consideration when suggesting a better design to this problem.
Here is a simplified version of the code I'm working on, and as such it might seem contrived. If so I apologize. Consider the following classes:
// Foo is a class that wraps underlying functionality from another
// assembly to create a simplified API. Think of this as a service layer class,
// a facade-like wrapper. It contains a helper class that is specific to
// foo. Other AbstractFoo implementations have their own helpers.
public class Foo : AbstractFoo
{
private readonly DefaultHelper helper;
public override DefaultHelper Helper { get { return helper; } }
public Foo()
{
helper = new Helper("custom stuff");
}
public override void Operation1(string value)
{
Console.WriteLine("Operation1 using " + value);
}
public override void Operation2()
{
Console.WriteLine("Operation2");
}
}
// Helper derives from a default implementation and allows us to
// override it's methods to do things specific for the class that
// holds this helper. Sometimes we use a custom helper, sometimes
// we use the default one.
public class Helper : DefaultHelper
{
private readonly string customStuff;
public Helper(string value)
{
customStuff = value;
}
public override void DoSomethingHelpful()
{
Console.WriteLine("I was helpful using " + customStuff);
}
}
Say these two class are used as follows:
// foo referenced and used in one part of code
var foo = new Foo();
foo.Operation2(); // or foo.Operation1();
// some other point in the program where we don't have a reference to foo
// but do have a reference to the helper
helper.DoSomethingHelpful();
However I now find out that I also need to perform foo.Operation1 in some implementations of helper.DoSomethingHelpful();? Potential workarounds I thought of would be:
Have foo and helper have a bidirectional relationship. So that in DoSomethingHelpful we can call foo.Operation2
Have foo implement IHelp interface and move the "helper" code into foo
Use delegation and pass the method Operation2 as an Action<string> delegate into the constructor of Helper.
None of these approaches seem to be ideal (though I've pretty much determined I don't like option 1 and am worried about maintainability with option 3 if we find out later we need to pass in more delegates). This makes me wonder if there is a problem with the initial design of the Helper/Foo combo. Thoughts?
How about a casual ("uses") relationship:
public class Helper : DefaultHelper
{
private readonly string customStuff;
public Helper(string value)
{
customStuff = value;
}
public override void DoSomethingHelpful(AbstractFoo foo)
{
foo.Operation1();
Console.WriteLine("I was helpful using " + customStuff);
}
}
So you modify the abstract helper to expect a reference to the proper Foo implementation.
"None of these approaches seem to be ideal (though I've pretty much
determined I don't like option 1 and am worried about maintainability
with option 3 if we find out later we need to pass in more delegates).
This makes me wonder if there is a problem with the initial design of
the Helper/Foo combo."
You're exactly right - there IS a problem with the design of Helper and Foo. The basic Foo/Helper relationship as you initially described it is fine, and is a common pattern when you have to wrap other objects that you do not control. But then you say:
"What if I find out that I also need to perform foo.Operation1 in some
implementations of helper.DoSomethingHelpful();?"
This is where we have a problem. You started out describing a relationship where Foo is dependent on Helper; now you are describing a relationship where Helper is dependent on Foo. That immediately tells me that your dependency relationships are tangled up. Dependency relationships between objects should only go one way; in fact dependency injection relies on this.
I think you have what you need. Try not to design for the "just in case I need it later" and don't fix what is not broken. If in the future you need to use Operation1 from your helper, then add it as a dependency on the constructor (as you suggested), or just pass it to the method you are calling. It will depend on the scenario, and you will have it when you actually need something.
EDIT: changed the "Try not to design for the future" as it doesn't seem what I want to say.
EDIT again due changes in the question
You could so something like this:
helper.DoSomethingUsefulWith( foo );
so your helper method will receive the dependency it needs in order to work
I think all your solutions are good; they just offer different capabilities. These differences don't matter too much now but are likely to in the future.
You prefer the second one, and your instincts are the best guide here, you knowing more than the rest of us about your code's future. I like your second solution the best just because it gets rid of a class and is simpler. Due to it's simplicity, if you have to do something else later, you won't have to throw away a lot of work.
The first method lets you play games with different Helper (IHelper?) instances and subclasses. The last method adds a lot of flexibility to Helper. (Although it may add so much you don't need Helper, just the method you're passing to it.) You can switch to using them later if either seems to solve more of the future's unguessed problems.
Consider the following:
public Something(IInterface concreteObjectOne, IInterface concreteObjectTwo)
{
this.concreteObjectOne = concreteObjectOne;
this.concreteObjectTwo = concreteObjectTwo;
}
How do I set set this type of binding up with Ninject? I'd try Googling the term, but as I'm not sure what this is called I can't, nor can I find anything on the Wiki about this.
Edit:
I believe this is called Convention Based Binding, as described here. However this documentation is for version 1.0 and 2.0 does not have the Only method. I'd like this to be achieved without attributes - using the convention of names or something similiar.
In addition to the use of "Only" method, the article suggests another solution by specifying different attributes for the injected objects.
Example:
public class ObjectOneAttribute : Attribute
{
}
public class ObjectTwoAttribute : Attribute
{
}
Then
public Something([ObjectOneAttribute] IInterface concreteObjectOne, [ObjectTwoAttribute] IInterface concreteObjectTwo)
{
this.concreteObjectOne = concreteObjectOne;
this.concreteObjectTwo = concreteObjectTwo;
}
And when you want to bind the interface to the correct concrete object, use the "WhereTargetHas" method:
Bind<IInterface>().To<YourConcreteTypeOne>().WhereTargetHas<ObjectOneAttribute>();
Bind<IInterface>().To<YourConcreteTypeTwo>().WhereTargetHas<ObjectTwoAttribute>();
Update: Solution without using attributes:
Use the method "When":
Bind<IInterface>().To<YourConcreteTypeOne>().When(r => r.Target.Name == "concreteObjectOne");
Bind<IInterface>().To<YourConcreteTypeTwo>().When(r => r.Target.Name == "concreteObjectTwo")
;
If I may be allowed to offer some general, instead of Ninject-specific, guidance on this, I would suggest that you reconsider your design slightly. The current constructor is vague because it offers no guidance about which implementation of IInterface that goes where - I realize that this is just a mock-up of your real API, and while the real API may offer more help to the human developer in the form of aptly named parameters, a machine like a DI Container cannot infer correct usage.
Many DI Containers offer some way to address such vagueness, for example by providing attributes you can use to associate names (metadata) with each dependency. AFAIR, Ninject has Inject attributes...
However, consider a couple of alternatives:
The first alternative is to encapsulate the two similar interface instances in an Parameter Object, like this:
public interface IParameterObject
{
IInterface ObjectOne { get; }
IInterface ObjectTwo { get; }
}
You can now change the constructor to take an instance of IParameterObject instead of the two interface instances themselves.
public Something(IParameterObject po)
{
this.concreteObjectOne = po.ObjectOne;
this.concreteObjectTwo = po.ObjectTwo;
}
This means that you can push configuration of IParameterObject to the Composition Root.
Another alternative to ponder is whether it makes sense to consider the case with two instances as just a special case of a more general design that takes any number of instances. This may not always be the case, but if it is, you can change the constructor to this:
public Something(IEnumerable<IInterface> objects)
I would personally prefer any of the above suggestions over anything that uses specific Ninject features, because it forces me to make the API more explicit in general, and thus more readable and maintainable.