Ninject用参数召唤图表

时间:2012-02-10 07:37:53

标签: c#-4.0 ninject-2

这是我的问题。我有一个演示者类,我们称之为'Presenter',它将IDataSource作为构造函数参数。 IDataSource接口有不同的实现。我希望能够将一些参数传递给Ninject,并且基于该参数,应该使用几个IDataSource实现中的一个。我在下面提供了一些示例代码。我认为我的解决方案非常难看,必须有一个更聪明,更清洁的方法来做到这一点。你们是怎么解决这类问题的?

这是我的示例代码

public class Presenter
{
    public Presenter(IDataSource dataSource)
    {
        DataSource = dataSource;
    }

    private IDataSource DataSource { get; set; }

    public List<string> GetData()
    {
        return DataSource.GetAll();
    } 
}

public class InMemoryDataSource : IDataSource
{
    public List<string> GetAll()
    {
        return new List<string> {"a", "b"};
    }
}

public class DbDataSource : IDataSource
{
    public List<string> GetAll()
    {
        return new List<string> { "1", "2" };
    }
}

public interface IDataSource
{
    List<string> GetAll();
}

public class Module : NinjectModule
{
    public override void Load()
    {
        Bind<Presenter>().To<Presenter>().Named("Db");
        Bind<Presenter>().To<Presenter>().Named("InMemory");
        Bind<IDataSource>().To<InMemoryDataSource>    ().WhenParentNamed("InMemory");
        Bind<IDataSource>().To<DbDataSource>().WhenParentNamed("Db");
    }
}

[Test]
public void Run()
    {
        using (var kernel = new StandardKernel(new Module()))
        {
            var p = kernel.Get<Presenter>(x => x.Name == "InMemory");

            foreach(var s in p.GetData())
            {
                Console.Out.WriteLine(s);
            }
        }
    }

1 个答案:

答案 0 :(得分:2)

这取决于你想做什么。我假设您要使用不同的数据库进行测试而不是生产。在这种情况下,将创建具有生产配置的模块,并简单地重新绑定所有测试:

public class Presenter
{
    public Presenter(IDataSource dataSource)
    {
        DataSource = dataSource;
    }

    private IDataSource DataSource { get; set; }

    public List<string> GetData()
    {
        return DataSource.GetAll();
    } 
}

public class InMemoryDataSource : IDataSource
{
    public List<string> GetAll()
    {
        return new List<string> {"a", "b"};
    }
}

public class DbDataSource : IDataSource
{
    public List<string> GetAll()
    {
        return new List<string> { "1", "2" };
    }
}

public interface IDataSource
{
    List<string> GetAll();
}

public class Module : NinjectModule
{
    public override void Load()
    {
        Bind<Presenter>().To<Presenter>();
        Bind<IDataSource>().To<DbDataSource>();
    }
}

[Test]
public void Run()
    {
        using (var kernel = new StandardKernel(new Module()))
        {
            kernel.Rebind<IDataSource>().To<InMemoryDataSource>();
            var p = kernel.Get<Presenter>();

            foreach(var s in p.GetData())
            {
                Console.Out.WriteLine(s);
            }
        }
    }