Unity: «новый» один класс на основе другого конкретного класса? - PullRequest
0 голосов
/ 08 марта 2011

Возможно, я пытаюсь «неправильно использовать» Unity здесь, но мне бы хотелось, чтобы Unity создала новый класс, не основанный на интерфейсе, который реализует класс newe'd up, а основанный на другом классе..

Это связано с разрешением конкретного типа DataMapper на основе имени объекта домена, передаваемого в вызов метода в объекте DataContext (в данном случае это конкретный DataContext для Sql Server)

 protected override IDataMapper<T> GetDataMapper<T>()
 {
        if (typeof(T) == typeof(Expert))
        {
            return (IDataMapper<T>)new ExpertDataMapper();
        }
        else if (typeof(T) == typeof(Case))
        {
            return (IDataMapper<T>)new CaseDataMapper();
        }
        else if (typeof(T) == typeof(CaseFile))
        {
            return (IDataMapper<T>)new CaseFileDataMapper();
        }
        etc... etc...
}

Вы получите точку.

в этом случае T будет именем объекта домена, а НЕ именем DataMapper, который реализует интерфейс IDataMapper ... так что вызовэто:

IDataMapper<T> mapper = (IDataMapper<T>)container.Resolve(t);

не удается.

В вызове GetDataMapper используются универсальные шаблоны, и на основе имени объекта домена (скажем, «Эксперт») я хочу создать экземпляр объекта ExpertDataMapper,и вернуть это.

Что мне не нужно, так это «тупой» фабричный подход, в котором содержится огромный список операторов case ... особенно, когда приходит время добавлять новые доменные объекты и онисвязанные DataMappers.Я предпочел бы справиться с этим в разделе конфигурации моего файла App.config и НЕ должен входить, изменять код, перекомпилировать и затем выпускать в производство.

Может быть, Unity - неподходящий инструмент для работы?

Спасибо!Mike

Ответы [ 2 ]

1 голос
/ 09 марта 2011

Вы не можете зарегистрировать IDataMapper<Category> в файле конфигурации, потому что это синтаксис C #, но не имя универсального типа.Проверьте правила из имен типов здесь .

Вы должны использовать что-то вроде (упрощенная конфигурация Unity 2.0):

<unity>
  <alias alias="ICategoryMapper" 
         type="MyNamespace.IDataMapper`1[MyNamespace.Category], MyAssembly" />
  <alias alias="CategoryDataMapper" 
         type="MyNamespace.CategoryDataMapper, MyAssembly" />
  <container>
    <register type="ICategoryMapper" mapTo="CategoryDataMapper" />
  </container> 
</unity>
0 голосов
/ 08 марта 2011

Ладно, после того, как я немного поковырялся, у меня все получилось так:

    Type t = typeof(T);
    UnityContainer container = new UnityContainer();
    container.RegisterType<IDataMapper<Category>, CategoryDataMapper>();
    container.RegisterType<IDataMapper<Expert>, ExpertDataMapper>();
    etc... etc...

    IDataMapper<T> mapper = (IDataMapper<T>)container.Resolve<IDataMapper<T>>();

, который, казалось, делал это!

но если я продолжу использовать .RegisterType <>, я снова в той же лодке ... просто вместо набора операторов Case, я знаю, есть несколько строк .RegisterType <> ...

Поэтому я пытаюсь переместить вызовы RegisterType в мой файл App.config, и у меня возникают проблемы с тем, как сопоставить универсальные интерфейсы с конкретными преобразователями ...

У меня это пока что, и оно не работает:

<unity>
<containers>
<container>
<types>
<type type="IDataMapper&lt;Category&gt;" mapTo="CategoryDataMapper">
</type>
</types>
</container>
</containers>
</unity>

Я также пробовал полное пространство имен, но без кубиков.Unity не любит пытаться загрузить тип "IDataMapper" ...

есть идеи?

...