Nano Hash - криптовалюты, майнинг, программирование

Внедрение установщика StructureMap в открытый универсальный тип?

Используя 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();

Это компилируется, но выдает исключение времени выполнения «не удается подключить к типу» при попытке разрешения.

Кто-нибудь знает, как в этом случае выполнить сеттер-инъекцию? Спасибо!

РЕДАКТИРОВАТЬ:

По запросу, вот подробный пример того, чего я пытаюсь достичь:

[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);
    }
}

Ответы:


1

Я предполагаю, что вы получаете Foo с помощью IMyInterface, а не запрашивая Foo. Итак, вы захотите сделать For (typeof (IMyInterface ‹,>)). Этот код работает у меня (с использованием исходного кода магистрали):

var container = new Container(x =>
{
    x.For<ISomeDependency>().Use<TheDependency>();
    x.For(typeof (IMyInterface<,>)).Use(typeof (Foo<,>)).SetterDependency<ISomeDependency>("Bar").IsAutoFilled();
});

var instance = (Foo<string, bool>)container.GetInstance(typeof (IMyInterface<string, bool>));
Console.WriteLine(instance.Bar.GetType().Name);

В качестве альтернативы вы можете настроить соглашение, чтобы ЛЮБОЙ тип, полученный из контейнера, который имеет свойство типа ISomeDependency, заполнялся:

var container = new Container(x =>
{
    x.For<ISomeDependency>().Use<TheDependency>();
    x.For(typeof (IMyInterface<,>)).Use(typeof (Foo<,>));
    x.SetAllProperties(set => set.OfType<ISomeDependency>());
});

Вы также можете основывать свои соглашения на других критериях, используя x.SetAllProperties (set => set.Matching (...))

14.01.2010
  • На самом деле я пытаюсь получить Foo, запрашивая Foo. Я пытаюсь приблизиться к функциональности ForConcreteType, который передает один и тот же конкретный тип как методам ForRequestedType, так и TheDefault.Is. Это потому, что Foo ‹T1, T2› абстрактно. На самом деле я разрешаю конкретный IFoo ‹T1, T2› на основе его общих типов. Если этот конкретный тип наследуется от абстрактного базового типа Foo ‹T1, T2›, я хочу, чтобы его свойство Bar было внедрено с ISomeDependency по умолчанию. Это проблема открытого универсального типа. Я проголосую за обходной путь SetAllProperties. Спасибо! 14.01.2010
  • Хорошо, полагаю, мне не следует строить предположения. Иногда бывает трудно последовать примеру, когда все IFoo и IMyInterface являются отвлекающими внимание именами (в вашем комментарии упоминается IFoo, чего не было в исходном посте). Можете ли вы опубликовать полный тест NUnit, демонстрирующий вашу проблему? Вы можете использовать вымышленные классы и интерфейсы, просто убедитесь, что вы включили их полное определение. 16.01.2010
  • Извините за все, что связано с Foo. Я согласен, это сбивает с толку. Я опубликовал правку, чтобы более подробно объяснить, что я пытаюсь сделать. Как видите, IHandler ‹TMessage› является базовым типом, а DatabaseTransactionHandler ‹TMessage› - это абстрактный класс, имеющий свойство Session: ISession. Сеанс используется наследниками DatabaseTransactionHandler ‹TMessage› для доступа к сеансу базы данных. Я хочу, чтобы это свойство вводилось без украшения его атрибутом [SetterDependency] или с помощью глобального метода SetAllProperties. Спасибо за любую помощь! 18.01.2010
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..