Конфигурация Unity и вложенные универсальные типы - PullRequest
4 голосов
/ 01 января 2011

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

Код выглядит примерно так:

public interface IFactory<T, TResult>
{
    TResult CreateInstance(T input);
}

public interface IFilter<T>
{
    // throws an exception if an item is to be filtered
    void Filter(T itemToFilter);
}

// classes implementing this interface can have multiple filters    
public interface IFilterRunner<T>
{        
    void RunFilters(T itemToFilter);
}

public class FilterRunnerFactory : IFactory<BaseType, IFilterRunner<BaseType>>
{
    public IFilterRunner<BaseType> CreateInstance(BaseType input)
    {
        if (input is SubType)
        {
            return new SubTypeFilterRunner();
        }

        throw new InvalidOperationException("Could not create an IFilterRunner for the input.");
    }
}

public class Service
{
    private readonly IFactory<BaseType, IFilterRunner<BaseType>> _filterRunnerFactory;

    public Service(IFactory<BaseType, IFilterRunner<BaseType>> filterRunnerFactory)
    {
        _filterRunnerFactory = filterRunnerFactory;
    }    
}

Конфигурация Unity выглядит примерно так:

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
  <alias alias="BaseType" type="SomeNamespace.BaseType, SomeAssembly, Version=1.0.0.0, Culture=neutral" />
  <alias alias="IFactory" type="SomeNamespace.IFactory`2, SomeAssembly, Version=1.0.0.0, Culture=neutral" />
  <alias alias="IFilterRunner" type="SomeNamespace.IFilterRunner`1, SomeAssembly, Version=1.0.0.0, Culture=neutral" />
  <alias alias="IService" type="SomeNamespace.IService, SomeAssembly, Version=1.0.0.0, Culture=neutral" /> 
  <containers>
    <container>
      <register type="IFactory[BaseType,IFilterRunner]" mapTo="SomeNamespace.FilterRunnerFactory, SomeAssembly, Version=1.0.0.0, Culture=neutral"/>

      <register type="IService" mapTo="SomeNamespace.Service, SomeAssembly, Version=1.0.0.0, Culture=neutral">
        <constructor>
          <param name="filterRunnerFactory" />
        </constructor>
      </register>
    </container>
  </containers>
</unity>

Конфигурация кажется действительной, но когда создается экземпляр самой службы WCF, я получаю следующую ошибку:

InvalidOperationException - The текущий тип, SomeNamespace.IFactory 2[SomeNamespace.BaseType,SomeNamespace.IFilterRunner 1 [SomeNamespace.BaseType]], это интерфейс и не может быть построен. Вы пропустили тип отображение

Я пробовал всевозможные варианты, но все они приводят к неверной конфигурации. Кроме того, у меня были другие фабричные определения, которые определены для возврата либо абстрактных базовых типов, либо экземпляров типов, основанных на неуниверсальных интерфейсах, и они работали нормально. Разница в том, что эта фабрика возвращает IFilterRunner - универсальный интерфейс.

У кого-нибудь есть предложения? Заранее спасибо от озадаченного разработчика.

1 Ответ

2 голосов
/ 15 февраля 2011

Я исправил вашу проблему, указав общий аргумент для псевдонима IFilterRunner.

<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
  <alias alias="BaseType" type="SomeNamespace.BaseType, SomeAssembly, Version=1.0.0.0, Culture=neutral" />
  <alias alias="IFactory" type="SomeNamespace.IFactory`2, SomeAssembly, Version=1.0.0.0, Culture=neutral" />
  <alias alias="IFilterRunner" type="SomeNamespace.IFilterRunner`1[[SomeNamespace.BaseType, SomeAssembly, Version=1.0.0.0, Culture=neutral]], SomeAssembly, Version=1.0.0.0, Culture=neutral" />
  <alias alias="IService" type="SomeNamespace.IService, SomeAssembly, Version=1.0.0.0, Culture=neutral" />
  <containers>
    <container>
      <register type="IFactory[BaseType,IFilterRunner]" mapTo="SomeNamespace.FilterRunnerFactory, SomeAssembly, Version=1.0.0.0, Culture=neutral"/>

      <register type="IService" mapTo="SomeNamespace.Service, SomeAssembly, Version=1.0.0.0, Culture=neutral">
        <constructor>
          <param name="filterRunnerFactory" />
        </constructor>
      </register>
    </container>
  </containers>
</unity>
...