Подключение общих интерфейсов в StructureMap - PullRequest
0 голосов
/ 15 января 2010

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

Дано:

public interface ILookup
{
}

public interface ISupplier : ILookup
{
}

public interface ITenant : ILookup
{
}

public class Supplier : ISupplier
{
}

public class Tenant : ITenant
{
}

public interface ILookupRepository<TLookup> where TLookup : ILookup
{
   void DoSomethingWith(TLookup lookup);
}

public class LookupRepository<TLookup> : ILookupRepository<TLookup> where TLookup : ILookup
{
   public void DoSomethingWith(TLookup lookup)
   {
      SaveOrWhatever(lookup);
   }
}

public class SomeClass
{   
   public void ProcessLookup(ILookup lookup)
   {
      // Get hold of a concrete class for ILookupRepository<TLookup> where TLookup is the type of the supplied
      // lookup. For example, if ProcessLookup is passed an ISupplier I want a LookupRepository<ISupplier>.
      // If it's passed an ITenant I want a LookupRepository<ITenant>.

      // var repository = ???

      repository.DoSomethingWith(lookup);
   }
}

Как мне получить StructureMap для предоставления SomeClass.ProcessLookup соответствующего LookupRepository<ISupplier> или LookupRepository<ITenant>? Возможно ли это без размышлений? Могу ли я вместо этого получить LookupRepository<Supplier> или LookupRepository<Tenant> вместо

Обновление:

Прочитав первоначальный ответ Ричарда, я понял, что мой первоначальный вопрос не очень хорошо выразил мою проблему (в конце концов, это пятница!). Я имею дело не только с одной реализацией ILookup, и хочу иметь возможность получить правильный ILookupRepository для типа, который я предоставляю. Я обновил вопрос выше, чтобы, надеюсь, более точно отражать мои требования.

Обновление 2:

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

1 Ответ

1 голос
/ 15 января 2010

[Отредактировано как первоначальные ответы, не отвечая на реальный вопрос]

Когда мне нужно сделать что-то подобное, я использую именованные экземпляры. К сожалению, я не могу придумать какой-либо простой способ сделать то, что вам нужно, без введения неуниверсального интерфейса. Неуниверсальный интерфейс будет выглядеть следующим образом (и, надеюсь, на самом деле не будет общедоступным):

public interface ILookupRepository
{
   void DoSomethingWith(object lookup);
}

Заставить ILookupRepository наследовать от неуниверсального интерфейса ILookupRegistry. Затем в StructureMap 2.5.4 вы можете сделать что-то вроде этого:

 For<ILookupRepository>().Add<LookupRepository<Supplier>>()  
    .Named(typeof(Supplier).FullName);
 For<ILookupRepository>().Add<LookupRepository<Tenant>>()  
    .Named(typeof(Tenant).FullName);

Затем получите репозиторий поиска в вашем методе, используя

var repo = ObjectFactory.GetInstance<ILookupRepository>(lookup.GetType().FullName);

ПРИМЕЧАНИЕ. Возможно, будет лучше (если это возможно), если интерфейс ILookup предоставляет механизм для определения типа. Например. конкретный Арендатор (или все, что унаследовано от него) вернет «ITenant», что позволит использовать этот же репозиторий поиска при необходимости.

Поможет ли это сейчас?

...