【问题标题】:How to create a Moq provider for Ninject?如何为 Ninject 创建 Moq 提供程序?
【发布时间】:2011-07-29 18:25:33
【问题描述】:

我想创建一个简单的 Ninject 提供程序,它返回 Moq 的实例而不是具体类型。到目前为止,我有这个:

public class NinjectMockProvider<T> : IProvider
{
    public static Type Type { get { return typeof(T); } }

    public object Create(IContext context)
    {
        Mock<T> newMock = new Mock<T>();
        return newMock.Object;
    }
}

但我敢肯定这都是错误的,因为我不知道自己在做什么。任何帮助和代码示例都会很棒。我只想有能力做:

kernel.Bind<ISomeInterface>().ToProvider<NinjectMoqProvider<ISomeInterface>>();

或类似的东西。

更新

我确实发现我可以通过使用 Ninject 的方法绑定来完成我想要的:

kernel.Bind<ISomeInterface>().ToMethod(x => new Mock<ISomeInterface>().Object);

我仍然想要一种更优雅的方式,我可能必须按照 Ian 的建议查看 Ninject.Moq,但如果有人有任何真实的代码示例,那就太棒了。

【问题讨论】:

  • 谢谢,方法绑定的例子很棒

标签: c# .net dependency-injection moq ninject


【解决方案1】:

MockingKernel 扩展可以处理您需要的内容吗?它有 Moq、RhinoMocks 和 NSubstitute 口味,也可以在 NuGet 上使用。

【讨论】:

  • 我确信它可能会,但我正在寻找自己的简单包装器,以便更好地理解它。
  • 我建议查看扩展的源代码,因为它可以提供一些关于模拟内核的见解。
【解决方案2】:

我对此的解决方案总是使用以下方法:

MoqProvider

public class MoqProvider<T> : Provider<T> // T is the desired service
{
    protected override T CreateInstance(IContext context)
    {
        return new Mock<T>().Object;
    }
}

然后我还向我的内核注册了一个IMissingBindingResolverMoqMissingBindingResolver 只是为尚未存在绑定的任何服务创建到 MoqProvider 的新绑定。

MoqMissingBindingResolver

public class MoqMissingBindingResolver : NinjectComponent, IMissingBindingResolver
{
    public IEnumerable<IBinding> Resolve(Multimap<Type, IBinding> bindings, IRequest request)
    {
        if (request.Service.IsAbstract || request.Service.IsInterface)
        {
            var moqProvider = (IProvider)Activator.CreateInstance(typeof(MoqProvider<>).MakeGenericType(request.Service));
            return new IBinding[] 
            { 
                new Binding(request.Service, new BindingConfiguration 
                { 
                    ProviderCallback = ctx => moqProvider,
                    ScopeCallback    = Settings.DefaultScopeCallback
                }) 
            }; 
        }
        else
        {
            return Enumerable.Empty<IBinding>();
        }
    }
}

我通常还将Settings.DefaultScopeCallback 设置为单例,以便稍后当我需要验证某些调用是否发生时,我可以在测试中请求我的模拟对象,或者在执行测试之前设置模拟行为.所以设置我的内核将如下所示:

INinjectSettings Settings = new NinjectSettings 
{ 
    DefaultScopeCallback = StandardScopeCallbacks.Singleton    
};

var k = new StandardKernel(Settings);
k.Components.Add<IMissingBindingResolver, MoqMissingBindingResolver>();

希望这有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多