инъекции зависимостей универсального типа: Как придать T

голоса
4

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

public interface IDocHandler<T>where T: class
{

T Document { get;set;}

void Load(T doc);

void Load(string PathToDoc);

void Execute();

void Execute(T doc);

}

А для различных типов документов, которые я реализовать этот интерфейс.

например:

public class FinanceDocumentProcessor:IDocumentHandler<ReportDocument>
{} 


public class MarketingDocumentProcessor:IDocumentHandler<MediaDocument>
{} 

Тогда я могу сделать, конечно, что-то вроде этого:

IDocumentHandler<ReportDocument> docProc= new FinanceDocumentProcessor();

Было бы interessting знать, как я могу вводить T во время выполнения, чтобы сделать линию выше loosly в сочетании ...

IDocumentHandler<ReportDocument> docProc = container.resolve(FinanceDocumentProcessor());

но я хочу, чтобы решить, в конфигурации кастрированный баран Я хочу, чтобы мой FinanceDomcumentProcessor или мой MarketingDocumentProcessor ... поэтому я бы впрыснуть T на левом сайте, тоже ... Так как я должен использовать C # 2.0 я не могу использовать волшебное слово «вар», которое помогло бы много в этом ... но как я могу спроектировать это быть открытым и гибким ...


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

Пример изображения у меня есть:

ReportingService, Crystal, ListAndLabel три типа отличаются отчетности документов. У меня есть общий HandlerIReportHandler<T> (будет таким же , как и выше) этот обработчик обеспечивает все функциональные возможности для обработки документа отчета. например

ChrystalReportHandler:IReportHandler<CrystalReportDocument>

Теперь я хочу использовать рамки как единства (или какую-нибудь рамку) для инъекции зависимостей, чтобы решить с помощью конфигурации, хочу ли я использовать кристалл, Reportingservices или список и этикетку.

Когда я указываю мое отображение я могу вводить мой , ChrystalReportHandlerно как я могу вводить T на левой стороне или в лучшем слове тип ReportDocument.

IReportHandler<T (this needs also to be injected)> = IOContainer.Resolve(MyMappedType here) 

Моя проблема заключается в левом сайт, конечно, потому что он связан с типом, но у меня есть отображение ... было бы возможно, чтобы создать объект на основе карт и присвоить отображенный тип? или в основном инъекционные T на левой стороне, тоже? Или этот подход не подходит для данной ситуации.

Задан 10/12/2008 в 10:05
источник пользователем
На других языках...                            


3 ответов

голоса
2

Я думаю , что с вашим текущим дизайном, вы создаете «зависимость» между IDocumentHandlerи конкретный документ ( ReportDocumentили MediaDocument) и поэтому , если вы хотите использовать IDocumentHandler<ReportDocument or MediaDocument>непосредственно в коде вы должны предположить , что ваш контейнер даст вам только что. Контейнер не должен нести ответственность за решение типа документа в данном случае.

Считаете ли вы изменить свой дизайн, как это?

public interface IDocumentHandler
{
    IDocument Document { get; set; }

    void Load(IDocument doc);

    void Load(string PathToDoc);

    void Execute();

    void Execute(IDocument doc);

}

public class IDocument { }
public class ReportDocument : IDocument { }
public class MediaDocument : IDocument { }
public class FinanceDocumentProcessor : IDocumentHandler { }
public class MarketingDocumentProcessor : IDocumentHandler { }
Ответил 10/12/2008 в 11:20
источник пользователем

голоса
1

Если я вас правильно понимаю, у вас есть два варианта.

  1. если у вас есть интерфейс IDocHandler и несколько классов , реализующих его, вы должны зарегистрировать каждый тип в явном виде, как это:

    container.AddComponent> (TypeOf (FooHandler));

  2. если у вас есть один класс DocHandler можно зарегистрировать с компонентом с использованием открытого универсального типа

    container.AddComponent (TypeOf (IDocHandler <>), TypeOf (DocHandler <>));

то каждый раз, когда вы решить IDocHandler вы получите экземпляр DocHandler и когда вы разрешить IDocHandler вы получите DocHandler

надеюсь, это поможет

Ответил 22/12/2008 в 23:27
источник пользователем

голоса
1

Вы должны использовать не универсальный интерфейс на левой стороне.

Пытаться:

public interface IDocumentHandler { }
public interface IDocumentHandler<T> : IDocumentHandler { }

Это создаст два интерфейса. Положите все общее, не-Т-специфическое в основной интерфейс, и все остальное в родовом один.

Так как код, который вы хотите разрешить объект в, что вы не знаете тип процессора для, вы не могли бы назвать какой-либо из T-специфического кода в любом случае, так что вы не потеряете ничего, используя НЕРАСПРОСТРАНЕНИИ -генерическая интерфейс.


Изменить : Я заметил , что мой ответ был downvoted. Было бы хорошо , если бы люди downvoting вещи бы оставить комментарий , почему они сделали это. Я не забочусь о точке репутации, что лишь небольшой шум на данный момент, но если есть что - то серьезно не так с ответом, то я хотел бы знать , так что я могу либо удалить ответ (если это далеко цель ) или исправить ее.

Теперь в этом случае я подозреваю, что либо оригинал questionee имеет downvoted, и, таким образом, либо не писал достаточно информации, так что на самом деле он спрашивает о чем-то другом, чем то, что он спросил об этом, или он не совсем понял мой ответ, который понятно, так как это было немного меньше, или что кто-то, кто не понял downvoted это, опять-таки по той же причине.

Теперь, чтобы уточнить.

Вы не можете ничего «на левой стороне» впрыснуть. Это невозможно. Этот код должен компилировать, быть правильным, и быть 100% «там» во время компиляции. Нельзя сказать, что «мы расскажем вам, что Т во время выполнения» для этой части. Это просто не возможно.

Таким образом, вы остались только то, чтобы удалить T в целом. Сделать код, который использует зависимость не зависит от Т, вообще. Или, по крайней мере, использовать отражение, чтобы узнать, что Т и делать вещи, основываясь на этом знании.

Это все, что вы можете сделать. Вы не можете сделать код на самой левой стороне изменения в зависимости от того, что вы вернетесь из метода на правой стороне.

Это не представляется возможным.

Поэтому мой ответ.

Ответил 10/12/2008 в 10:39
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more