关于输入C#

Ter*_*Liu 9 c#

我尝试使用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)

但是,看起来,我总是nullGetService()函数返回.相反,我希望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注册模式来实现这种通用性.

  • @CodeNotFound请不要通过编辑我的答案把话语放在嘴里.OP的服务定位器的具体实现很糟糕.我不相信我们不应该使用它,或者它在复杂系统中没有位置. (2认同)

Fab*_*jan 4

我尝试使用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 框架的广告。随意使用任何其他框架,我在本示例中使用了它,因为我更熟悉它