Reputation: 111
I tried to use C# DI method to implement something. following is my code snippet.
public interface IMessageService
{
void Send(string uid, string password);
}
public class MessageService : IMessageService
{
public void Send(string uid, string password)
{
}
}
public class EmailService : IMessageService
{
public void Send(string uid, string password)
{
}
}
and code that creates a ServiceLocator
:
public static class ServiceLocator
{
public static object GetService(Type requestedType)
{
if (requestedType is IMessageService)
{
return new EmailService();
}
else
{
return null;
}
}
}
now, I create a test code with
public class AuthenticationService
{
private IMessageService msgService;
public AuthenticationService()
{
this.msgService = ServiceLocator
.GetService(typeof(IMessageService)) as IMessageService;
}
}
but, it looks like, I always get null
returned by GetService()
function. Instead I expect to get EmailService
object via GetService()
function, so how to do it correctly?
Upvotes: 9
Views: 550
Reputation: 13676
I tried to use C# DI method to implement something. following is my code snippet
There is no such pattern called "C# DI method". I presume that our task here is to use a ServiceLocator pattern for DI. Don't do that!
The ServiceLocator is arguably an anti-pattern and leads to maintenance nightmare because class dependencies are hidden. In most real-world scenarios we should avoid using it.
With help of some DI framework such as SimpleInjector
(it could be any other well-known DI framework though) you could achieve the same result. However this time the code will be more maintainable and a lot easier to test.
For that we could create a Mock<IMessageService>
and pass its object to a constructor of EmailService
.
But let's get back to the subject and have a look into how we could use Simpleinjector
here:
public class AuthenticationService
{
private readonly IMessageService _msgService;
public AuthenticationService(IMessageService msgService)
{
this._msgService = msgService;
}
}
In order to use that somewhere in code we need to register this dependency. A minimal code example would be:
var container = new SimpleInjector.Container();
container.Register<IMessageService, EmailService>();
container.Verify();
And that's all it requires!
P.S. This is not an ad of this particular DI framework. Feel free to use any other framework, I've used it in this example because I'm more familiar with it
Upvotes: 4
Reputation: 9509
What you are passing in is an instance of Type
.
So this condition requestedType is IMessageService
is never true
.
What you need to do is
public static object GetService(Type requestedType)
{
if (requestedType == typeof(IMessageService))
{
return new EmailService();
}
else
{
return null;
}
}
As a side note, this is quite a bad pattern - your so-called service locator
has concrete knowledge of concrete types. You're better off using reflection or some traditional registration pattern for IoC to make this generic.
Upvotes: 12