C# dependency injection - how to you inject a dependency without source?
I am trying to get started with some simple dependency injection using C# and i've run up against an issue that I can't seem to come up with an answer for.
I have a class that was written by another department for which I don't have the source in my project. I wanted to inject an object of this type though a constructor using an interface, but of course, i can't change the injected objects implementation to implement the interface to achieve polymorphism when casting the object to the interface type.
Every academic example I have ever seen of this technique has the classes uses classes which are declared in the project开发者_如何学编程 itself. How would I go about injecting my dependency without the source being available in the project?
I hope that makes sense, thanks.
You could create a wrapper around your target type, so for example, you could have a class they provide:
public class TheirClass
{
public void DoSomething();
}
With which you can define an interface:
public interface ITheirClass
{
void DoSomething();
}
And implement that interface on a wrapper class:
public class TheirClassWrapper : TheirClass, ITheirClass
{
}
Or, if the class they provided is sealed, you need to do it slightly differently:
public class TheirClassWrapper : ITheirClass
{
private TheirClass instance = new TheirClass();
public void DoSomething()
{
instance.DoSomething();
}
}
Then you can inject that interface instead.
I know in MEF we can export concrete types and have them injected correctly, but I'm not sure about other IoC containers.
The question is, why do you want to inject it as an interface? Is it because the class implements some properties/methods that you'd like to abstract out so it can be substituted, or are you just trying to "force" a marker interface onto it because "we always depend on interfaces, not concrete classes" ? If it's the latter then you're on the wrong path as you'd likely just cast it to the concrete immediately anyway.
Assuming the former of the two I can see two options:
- Use inheritance instead. This may or may not be possible depending on the class has been created, but you could inherit from it and substitute your new class for the old one.
- Create the interface yourself, with the methods/properties you require and wrap the external concrete class in a class that implements the interface.
For option 2, if you can't inherit, as an example, assuming you only care about one method in the class (we'll call it Method1()) you create a matching interface for it:
public interface IMyNewInterface
{
void Method1();
}
Then create an implementation of it that takes the concrete class as a dependency (injected by your container as normal) that just calls the concrete class:
public class MyNewClass : IMyNewInterface
{
private MyConcreteClass _MyConcreteClass;
public void MyNewClass(MyConcreteClass concreteClass)
{
_MyConcreteClass = concreteClass;
}
public void Method1()
{
_MyConcreteClass.Method1();
}
}
If you dont have the need to change anything in a class, you hardly need the code. Lets assume you have a class X in a DLL that you wish to inject to another class Y that you are writing. In such a case you can create an instance of X and put as the parameter in the constructor of Y. This will look something like this:
Add a reference to the DLL containing class X in your project.
Use NameSpaceOfX;
Class Y
{
Public Y() //Default constructor
{
}
Public Y(X instanceOfX)
{
//Use instanceOfX here as required
}
}
In you main code:
//Create instance of X
X instanceOfX = new X();
//Inject it into Y
Y instanceOfY = new Y(instanceOfX);
//Use Y now.
精彩评论