.NET Framework объект, который использует Dependency Injection? - PullRequest
4 голосов
/ 04 октября 2010

Я пытаюсь найти пример в .NET класса, который использует Dependancy Injection (например, класс, который использует Builder или Factory, чтобы создать полный объект - вводить зависимости как есть)

Просматривая Reflector, я бы подумал, что некоторые из более сложных ado.net или WebRequest объектов будут использовать внедрение зависимостей - но нет.

Может ли кто-нибудь указать на пример внутри .NET-инфраструктуры объекта, который использует внедрение зависимостей для выполнения своей работы?

Ответы [ 4 ]

3 голосов
/ 05 октября 2010

Вот несколько примеров внедрения зависимостей в платформе:

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

System.Xml выполняет внедрение зависимостей бедного человека во многих местах.Например, XmlDocument имеет инъекцию конструктора (внутреннюю) в XmlImplementation.Конструктор по умолчанию просто создает экземпляр необходимого XmlImplementation.Само XmlImplementation зависит от XmlNameTable.XmlResolvers - еще один пример внедрения.

MEF CompositionContainer опционально зависит от ComposablePartCatalog и ExportProviders. ImportEngine имеет инъекцию конструктора ExportProvider

Контроллер ASP.NET MVC имеет инъекцию сеттера на IActionInvoker и ITempDataProvider (у них есть реализации по умолчанию).вы только начинаете с внедрения зависимостей, IMHO. .NET Framework - худшее место, из которого вы можете извлечь уроки: большую часть времени у вас не будет исходного кода, это код уровня платформы (не уровня приложения) с совершенно особеннымтребования.В частности, Microsoft очень старается обнародовать информацию (по умолчанию внутренняя), в отличие от большинства проектов с открытым исходным кодом, чтобы лучше управлять их критическими изменениями.

2 голосов
/ 09 декабря 2012

В .NET Framework есть много мест, где используется Dependency Injection.Прежде всего .NET Framework использует множество шаблонов GoF, и некоторые из них в значительной степени зависят от внедрения зависимостей.Например, Шаблон проектирования декоратора всегда использует конструктор Injection, а Шаблон проектирования стратегии использует конструктор Injection или Method Injection:

// Decorator on Streams (uses Constructor Injection)
var ms = new MemoryStream();
var bs = new BufferedStream(ms);

// Strategy of sorting (uses Method Injection)
var list = new List<int>();
list.Sort(new CustomComparer());

// Strategy of sorting (Constructor Injection)
var sortedArray = new SortedList<int, string>(
                        new CustomComparer());

// Strategy of starting new task using TaskScheduler
// (Method Injection)
var task = Task.Factory.StartNew(
    () => { }, 
    CancellationToken.None, 
    TaskCreationOptions.None, 
    TaskScheduler.Default);

    // All method that takes IFormatProvider and
    // similar strategies is an example of the Method Injection
    IFormatProvider provider = null;
    42.ToString(provider);

Любое использование Абстрактная фабрикаШаблон проектирования означает, что вы собираетесь «внедрить» объект фабрики, используя конструктор «Инъекция» или «Инъекция метода», и в .NET Framework есть множество примеров этого шаблона, например DbProviderFactory .

Чтобы получить больше примеров, которые покажут, что типы BCL используют Constructor Injection, я написал простой запрос LINQ (я покажу его позже), который перечисляет все доступные типы для поиска типов с помощью открытого конструктора, который принимает интерфейс илиабстрактный тип как параметр.В этом запросе было показано много других применений Constructor Injection в .NET Framework (здесь приведены некоторые примеры):

// ResourceReader takes a Stream
Stream ms = new MemoryStream();
var resourceReader = new ResourceReader(ms);

// BinaryReader/BinaryWriter, StreamReader/StreamWriter
// takes a Stream as well
var textReader = new StreamReader(ms);

// MethodCall takes a IMessage
IMessage message = new System.Runtime.Remoting.Messaging.MethodResponse(null, null);
var methodCall = new System.Runtime.Remoting.Messaging.MethodCall(message);

// Icon takes a Stream
var icon = new System.Drawing.Icon(ms);

// DbEnumerator takes a IDataReader
IDataReader dataReader = new DataTableReader(new DataTable());
var dbEnumerator = new System.Data.Common.DbEnumerator(dataReader);

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

var types =
    AppDomain.CurrentDomain.GetAssemblies()
        .SelectMany(a => a.GetTypes())
        .SelectMany(t => t.GetConstructors()
                                .Where(c => c.GetParameters()
                                                .Any(cp =>
                                                    (cp.ParameterType.IsAbstract ||
                                                    cp.ParameterType.IsInterface))))

        .Select(ci => new {Type = ci.DeclaringType, Constructor = ci.GetConstructorInfo()})
        .Where(t => !t.Type.Namespace.Contains("Internal"));
1 голос
/ 04 октября 2010

Я думаю, что DI замусорился по всей .NET Framework, но это особая форма DI, называемая «Внедрение свойств» - в мире Java ее часто называют «Внедрение сеттера».

0 голосов
/ 06 октября 2010

Вот очень простой (глупый) пример внедрения зависимости через фабрику:

public class MyService1Factory {
    public IMyService1 Create() {
        MyService2 service = new MyService2();
        // provides dependent IMyService2 for MyService
        return new MyService(service);
    }
}

public class MyService : IMyService1 {
    private IMyService2 service;

    // MyService depends upon IMyService2, an instance of this "dependency" is 
    // passed in (or "injected") via a simple constructor param
    public MyService(IMyService2 myService2) {
        service = myService2;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...