2010-01-15 2 views
0

Есть несколько вопросов о SO о StructureMap и дженериках, и я прочитал несколько сообщений в блоге об этом, но все же я изо всех сил стараюсь найти решение для этого конкретного сценария.Проводка общих интерфейсов в 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>?

Update:

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

Update 2:

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

ответ

1

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

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

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», позволяя повторному использованию такого же репозитория поиска, когда это применимо.

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

+0

Спасибо за ваш ответ. Думаю, я должен был быть яснее, чем был в моем вопросе, поскольку это, к сожалению, не помогает. Я уточню свой вопрос с дополнительной информацией. –

+0

Я тоже обновил свой ответ ... Я не очень доволен этим (возможно, лучшее решение), но он может указывать на вас в правильном направлении. –

+0

Это дает некоторую пищу для размышлений, спасибо. –

Смежные вопросы