我尝试使用C#DI方法来实现一些东西.以下是我的代码片段.
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)
{
}
}
Run Code Online (Sandbox Code Playgroud)
和代码创建一个ServiceLocator:
public static class ServiceLocator
{
public static object GetService(Type requestedType)
{
if (requestedType is IMessageService)
{
return new EmailService();
}
else
{
return null;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我用它创建一个测试代码
public class AuthenticationService
{
private IMessageService msgService;
public AuthenticationService()
{
this.msgService = ServiceLocator
.GetService(typeof(IMessageService)) as IMessageService;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,看起来,我总是null被GetService()函数返回.相反,我希望EmailService通过GetService()函数得到对象,那么如何正确地做到这一点呢?
zai*_*man 12
你传递的是一个实例Type.
所以这种情况requestedType is IMessageService永远不会true.
你需要做的是
public static object GetService(Type requestedType)
{
if (requestedType == typeof(IMessageService))
{
return new EmailService();
}
else
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
作为旁注,这是一个非常糟糕的模式 - 你所谓service locator的具体类型的具体知识.你最好使用反射或一些传统的IoC注册模式来实现这种通用性.
我尝试使用C# DI方法来实现一些东西。以下是我的代码片段
不存在称为“C# DI 方法”的模式。我认为我们这里的任务是使用 ServiceLocator 模式进行 DI。不要那样做!
ServiceLocator 可以说是一种反模式,并且会导致维护噩梦,因为类依赖性是隐藏的。在大多数现实场景中,我们应该避免使用它。
借助某些 DI 框架(例如SimpleInjector(但也可以是任何其他众所周知的 DI 框架)),您可以实现相同的结果。然而,这一次代码将更易于维护并且更容易测试。为此,我们可以创建 aMock<IMessageService>并将其对象传递给 的构造函数EmailService。
但让我们回到主题并看看我们如何在这里使用Simpleinjector:
public class AuthenticationService
{
private readonly IMessageService _msgService;
public AuthenticationService(IMessageService msgService)
{
this._msgService = msgService;
}
}
Run Code Online (Sandbox Code Playgroud)
为了在代码中的某个地方使用它,我们需要注册这个依赖项。一个最小的代码示例是:
var container = new SimpleInjector.Container();
container.Register<IMessageService, EmailService>();
container.Verify();
Run Code Online (Sandbox Code Playgroud)
这就是它所需要的一切!
PS 这不是这个特定 DI 框架的广告。随意使用任何其他框架,我在本示例中使用了它,因为我更熟悉它