Ninject графы вызова с аргументом - PullRequest
1 голос
/ 10 февраля 2012

Вот моя проблема. У меня есть класс Presenter, давайте назовем его «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 Ответ

2 голосов
/ 10 февраля 2012

Это зависит от того, что вы хотите сделать. Я предполагаю, что вы хотите использовать другую базу данных для тестирования, чем для производства. В этом случае создайте модуль с учетом производственной конфигурации и просто перепроверьте все для тестирования:

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);
            }
        }
    }
...