Используя StructureMap, я пытаюсь использовать сеттерное внедрение для открытого универсального типа.
У меня есть абстрактный обобщенный класс:
public abstract class Foo<T1, T2> : IMyInterface<T1,T2>
{
public ISomeDependency Bar { get; set; }
}
Я хочу использовать Setter Injection для разрешения «Bar» на любых наследниках Foo. Я знаю, что могу сделать это с помощью атрибута [SetterDependency] в Bar, но я хочу избежать декорирования своего класса таким образом.
Я думал, что мог бы использовать ForConcreteType в DSL следующим образом:
ForConcreteType (TypeOf (Foo <,>)) Configure.Setter () IsTheDefault ();..
Но ForConcreteType имеет только общую реализацию.
Я попытался сделать это в конфигурации следующим образом:
For(typeof (Foo<,>))
.Use(typeof (Foo<,>)).SetterDependency<ISomeDependency>("Bar").IsAutoFilled();
Это компилирует, но выдает исключение времени выполнения "нельзя подключить к типу" при попытке разрешить.
Кто-нибудь знает, как в этом случае выполнить инъекцию сеттера? Спасибо!
EDIT:
В соответствии с просьбой, вот подробный пример того, чего я пытаюсь достичь:
[Test]
public void can_resolve_open_generic_type_using_setter_injection()
{
ObjectFactory.Initialize(x =>
{
x.For<ISession>().Use<DatabaseSession>();
// uncomment next line and it resolves:
// x.SetAllProperties(set => set.OfType<ISession>());
x.ForRequestedType<IHandler<OrderReceivedMessage>>()
.TheDefaultIsConcreteType<OrderHandler>();
});
var instance = ObjectFactory.Container.GetInstance<IHandler<OrderReceivedMessage>>();
instance.ShouldBeOfType<DatabaseTransactionHandler<OrderReceivedMessage>>();
instance.ShouldBeOfType<OrderHandler>();
var asTransactionHandler = (DatabaseTransactionHandler)instance;
Assert.IsNotNull(asTransactionHandler.Session);
}
public interface IHandler<TMessage>
{
void Handle(TMessage message);
}
public abstract class DatabaseTransactionHandler<TMessage> : IHandler<TMessage>
{
// need to inject this with the default ISession
// works when using [SetterDependency] attribute
public ISession Session { get; set; }
public abstract void DoHandle(TMessage message);
public virtual void Handle(TMessage message)
{
using (ITransaction transaction = Session.CreateTransaction())
{
try
{
DoHandle(message);
transaction.Commit();
}
catch (Exception handlerException)
{
transaction.Rollback();
throw;
}
}
}
}
public class OrderHandler : DatabaseTransactionHandler<OrderReceivedMessage>
{
public override void DoHandle(OrderReceivedMessage message)
{
Order order = CreateOrderFromMessage(message);
Session.Save(order);
}
}