そのメソッドでこれらの型をインスタンス化するだけでよい場合は、それらをクラスに注入しないでください。
代わりに、一般的な解決策は、メソッドがインターフェイスを解決できるようにするファクトリを注入することです。
通常のアプローチは次のとおりです。
interface IMessageFactory
{
IMessage CreateMessage(string text);
}
class ConcreteMessageFactory : IMessageFactory
{
IMessage CreateMessage(string text) { return new Message(text); }
}
class MockMessageFactory : IMessageFactory
{
public IMessage CreateMessage(string text) { return new MockMessage(text); }
}
class MyClient
{
private readonly IMessageFactory _msgFactory;
public MyClient(IMessageFactory msgFactory)
{
_msgFactory = msgFactory;
}
public void SendMessage(string text)
{
IMessage msg = _msgFactory.CreateMessage(text);
msg.Send();
}
}
//Usage:
new MyClient(new ConcreteMessageFactory());
//Mocking
new MyClient(new MockMessageFactory());
使用している DI フレームワークによっては、フレームワークによってこの方法が簡単になります。たとえば、Castle Windsor では、上記のインターフェイス ベースのファクトリとは対照的に、デリゲート ベースのファクトリを注入できます。
class MyClient
{
private readonly Func<string, IMessage> _msgFactory;
public MyClient(Func<string, IMessage> msgFactory)
{
_msgFactory = msgFactory;
}
public void SendMessage(string text)
{
IMessage msg = _msgFactory(text);
msg.Send();
}
}
//Usage:
new MyClient(() => new Message());
//Mocking
new MyClient(() => new MockMessage());