Фабрика объектов, которая создает объекты, которые требуют зависимостей - PullRequest
0 голосов
/ 28 октября 2010

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

using Core;
using Data;

public static class TagProcessorFactory
{
 public static ITagProcessor GetProcessor(string tag)
 {
    switch (tag)
    {
       case "gps0":
         return new GpsTagProcessor();
       case "analog_manager":
         return new AnalogManagerTagProcessor();
       case "input_manager":
         return new InputManagerTagProcessor();
       case "j1939":
         return new J1939TagProcessor(new MemcachedProvider(new[] {  "localhost" }, "DigiGateway"), new PgnRepository());
       default:
         return new UnknownTagProcessor();
    }
 }
}

Телефонный код

var processor = TagProcessorFactory.GetProcessor(tag.Name);

if (!(processor is UnknownTagProcessor))
{
    var data = processor.Process(unitId, tag.Values);

    Trace.WriteLine("Tag <{0}> processed. # of IO Items => {1}".FormatWith(tag.Name, data.Count()));
}

как вы можете видеть, у одного из моих элементов есть зависимости, и я пытаюсь выполнить тестовый код, и я хочу передать имитирующие репозитории и провайдеров кеша, но я могу подумать, что это можно сделать.

Это плохой дизайн, или у кого-нибудь есть идеи по его исправлению, чтобы сделать мой завод пригодным для тестирования?

Спасибо

Ответы [ 3 ]

3 голосов
/ 29 октября 2010

Поскольку вы используете Autofac, вы можете воспользоваться типом отношения поиска :

public class Foo
{
    private readonly IIndex<string, ITagProcessor> _tagProcessorIndex;

    public Foo(IIndex<string, ITagProvider> tagProcessorIndex)
    {
        _tagProcessorIndex = tagProcessorIndex;
    }

    public void Process(int unitId, Tag tag)
    {
        ITagProcessor processor;

        if(_tagProcessorIndex.TryGetValue(tag.Name, out processor))
        {
            var data = processor.Process(unitId, tag.Values);

            Trace.WriteLine("Tag <{0}> processed. # of IO Items => {1}".FormatWith(tag.Name, data.Count()));
        }
    }
}

Для получения дополнительной информации см. Вики-статью TypedNamedAndKeysServices Чтобы зарегистрировать различные процессоры, вы должны связать каждый из них с его ключом:

builder.RegisterType<GpsTagProcessor>().Keyed<ITagProcessor>("gps0");
builder.RegisterType<AnalogManagerTagProcessor>().Keyed<ITagProcessor>("analog_manager");
builder.RegisterType<InputManagerTagProcessor>().Keyed<ITagProcessor>("input_manager");

builder
    .Register(c => new J1939TagProcessor(new MemcachedProvider(new[] {  "localhost" }, new PgnRepository()))
    .Keyed<ITagProcessor>("j1939");

Обратите внимание, что мы не регистрируемся UnknownTagProcessor. Это был сигнал производителю, что для тега не найден процессор, который мы выражаем с помощью TryGetValue.

0 голосов
/ 29 октября 2010

Я предлагаю вам просмотреть еще одну SO сообщение . Он решает сразу несколько проблем, включая замену значений в конструкторе - без проблем. В частности, параметры конструктора просто становятся статическими полями класса «Context», которые считываются конструктором внутреннего класса.

0 голосов
/ 29 октября 2010

Используя что-то вроде StructureMap, вы можете использовать ObjectFactory, который при настройке вернет вам именованный конкретный экземпляр.

http://structuremap.net/structuremap/index.html

...