Ninject加载不同的实现

时间:2013-12-12 15:36:39

标签: c# asp.net-mvc dependency-injection ninject inversion-of-control

我有一个使用接口(WebSite)的网络服务(我们称之为IDataService)。 webservice项目实现了一个带有硬编码对象(DesignDataService)的“虚假”服务,我在等待同事构建真正的实现时使用它来开发websit(BreadDataService)。

我的NinjectWebCommon目前是这样的:

private static void RegisterServices(IKernel kernel)
{
  kernel.Bind<IDataService>().To<DesignDataService>();
}

我想要的是能够为我的同事提供一种方法来测试我的WebService上的BreadDataService,同时我可以继续使用DesignDataService。我无法在我的机器上使用BreadDataService,因为它需要一些我没有的程序集(+数据库)。

那么,这里的方法是什么?当前的依赖树是这样的:

  • ServiceCore(定义{{​​1}})
  • IDataService使用WebSite
  • ServiceCore使用BreadDataService

我不想在ServiceCore项目中引用BreadDataService项目,我可能正在考虑WebSite中的一个文件夹,他们可以放置WebSite dll和ninject取决于web.config中的某些配置。

提示?

2 个答案:

答案 0 :(得分:2)

这样的事情可以解决问题

  • 加载外部程序集
  • 搜索实施
  • 如果没有找到,则默认为您的设计时版本

这是基本代码

IEnumerable<Assembly> assemblies = this.LoadAssemblies(@"C:\Temp");
Type implementation = FindImplementation(assemblies, typeof(IDataService));

IKernel kernel = new StandardKernel();

kernel.Bind<IDataService>().To(implementation ?? typeof(DesignDataService));

此方法将从特定文件夹

加载外部程序集(如插件)
private IEnumerable<Assembly> LoadAssemblies(string folder)
{
    IEnumerable<string> dlls =
        from file in new DirectoryInfo(folder).GetFiles()
        where file.Extension == ".dll"
        select file.FullName;

    IList<Assembly> assemblies = new List<Assembly>();

    foreach (string dll in dlls)
    {
        try
        {
            assemblies.Add(Assembly.LoadFile(dll));
        }
        catch
        {
        }
    }

    return assemblies;
}

此方法将搜索一组程序集以进行实现。请注意,我已经专门使用了SingleOrDefault(),因此如果有多个实现,这将失败。

private Type FindImplementation(
    IEnumerable<Assembly> assemblies, 
    Type serviceType)
{
    var implementationType = (
        from dll in assemblies
        from type in dll.GetExportedTypes()
        where serviceType.IsAssignableFrom(type)
        where !type.IsAbstract
        where !type.IsGenericTypeDefinition
        select type)
        .SingleOrDefault();

    return implementationType;
}

答案 1 :(得分:1)

我使用qujck方法构建这些extension methods。 主要区别在于它依赖于Ninject.Extensions.Conventions'FromAssembliesInPath方法