c# dependency injection -> look no interface :)
So I have a class with a method that calls a webservice.
I want to bring my class under test, so I have/want to remove the dependency on the webservice.
So the usual routine is:
- create an interface around dependencies in your class (DLs, Webservicecalls etc)
- let the dependencies implement their interface
- create constructor in your class that takes in instances of the new interfaces
But I just use this one method on the ws, and if I follow this I get
- one file for the interface
- one file using partial class to expand my automatic webproxy so that it implements the interface
- either a new constructor taking in the new interface,
- or I could send it in to the method actually doing the call,
but if I use several methods on the ws I would get many small interfaces littering my code
ie one for each method I’m using on the ws
It feels a little bit like overkill for the problem I have at hand.
This has been churning in the back of my mind lately, but I have just done this the usual way with constructor injection.
Then I was reading this post: http://blacksheep.parry.org/archives/diy-di
And one of the things that caught my attention was the Provider-pattern.
(Check out step 8 if you’re interested. )
While pondering it’s implication it suddenly dawned on me a solution to my webservice-dependency.
The way I use the webservice in my method is usually something like:
private IEnumerable<Duck> GetDucks(GetDucksParam param) {
IEnumerable<Duck> result = ws.GetListOfDucks(param);
….
return result;
}
Isn’t that a perfect match for a Func<T,TResult>?
Ie:
private IEnumerable<Duck> GetDucks(GetDucksParam param, Func<GetDucksParam ,IEnumerable<Duck>> GetDucksFunction) {
IEnumerable<Duck> result = GetDucksFunction(param);
….
return result;
}
This is still just in my mind, as I haven’t tested it yet, but doesn’t it seem like it should work...?
Benefits?
- No need for an interface, the Func is defining the contract
- No partial class hacking to extend the webproxy
- No new constructor, just send in the function that is going do the actual work
- You can use a lambda in your unit-test for the Func
I think I will have to try this.
Btw I would recommend reading the full post on http://blacksheep.parry.org/archives/diy-di
It’s an interesting read, for example:
“Mock objects
Too many mock objects, or mock objects that return other mock objects, should be a code smell. Ideally a unit test won’t use any mocks or stubs or fakes or dummies. Refactor the product code using inversion of control techniques, so that all classes ask directly for the values they need, not for the intermediaries that produce those values. (Good developers have spent the last few years honing their skills with mock objects, so this advice may come as a surprise. Strong testing habits no longer require the use of sophisticated mocking libraries.) “
Rgds from
Henri
No comments :
Post a Comment