代码之家  ›  专栏  ›  技术社区  ›  Ian Boyd

使用依赖项注入的.NET框架对象?

  •  4
  • Ian Boyd  · 技术社区  · 14 年前

    我试图在.NET中找到一个使用依赖注入的类(例如,使用 Builder Factory 为了创建完整的对象-像这样插入依赖项)

    浏览Reflector,我会想到一些更复杂的 ado.net WebRequest

    4 回复  |  直到 12 年前
        2
  •  2
  •   Sergey Teplyakov    12 年前

    Decorator Design Pattern Strategy Design Pattern

    // 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);
    

    任何用途 Abstract Factory Design Pattern 意味着您将要使用构造函数注入或方法注入来“注入”工厂对象,并且在.NET框架中有许多这样的模式示例 DbProviderFactory .

    为了获得更多的示例来显示BCL类型使用的是构造函数注入,我编写了一个简单的LINQ查询(稍后将显示它),它枚举所有可访问的类型,以查找具有接受接口或抽象类型作为参数的公共构造函数的类型。此查询显示了.NET框架中构造函数注入的许多其他用法(以下是一些示例):

    // 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框架包含更多依赖于此技术的类型。构造器注入在这个术语出现之前就已经被广泛使用了,所以我并不惊讶它被如此广泛地使用。您可以使用下面的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"));
    
        3
  •  1
  •   Randolpho    14 年前

    我认为在.NETFramework上到处都是垃圾,但它是一种特殊形式的DI称为“属性注入”——在Java世界中,它经常被称为“SETTER注入”。

        4
  •  0
  •   Max    14 年前

    下面是通过工厂进行依赖注入的一个真正简单(愚蠢)的例子:

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