DryIoC - 在解析时指定一些构造函数参数

rde*_*ago 5 c# dependency-injection dryioc

我正面临着与DryIoC相比令人费解的局面.

好吧,实际上,这是我第一次使用IoC容器,所以我可能只是误解了一切:从依赖注入到IoC容器,再到DryIoC本身.

尽管如此,我已经成为一名专业程序员已经有一段时间了,我有很好的谷歌搜索技巧,我甚至找不到其他人暴露的类似问题.

假设我有一个暴露这些接口的类库......

namespace Logging
{
    public interface ILogger
    {
        void Info(string message);
    }

    public interface ILoggerFactory
    {
        ILogger CreateLogger(string name);
    }
}
Run Code Online (Sandbox Code Playgroud)

...以及实现上述接口的另一个类库.

namespace Logging.Console
{
    internal class ConsoleLogger : ILogger
    {
        readonly string _name;

        public ConsoleLogger(string name)
        {
            _name = name;
        }

        void Info(string message) => System.Console.WriteLine($"[{_name}] {message}");
    }

    public class ConsoleLoggerFactory : ILoggerFactory
    {
        public ILogger CreateLogger(string name) => new ConsoleLogger(name);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后是第三个包含我需要的其他东西的库:

namespace LibraryA
{
    public interface IServiceA
    {
        // bla bla
    }

    public class ServiceA : IServiceA
    {
        // Implement service A
    }

    public interface IServiceB
    {
        // yada yada
    }

    public class ServiceB : IServiceB
    {
        // Implement service B
    }
}
Run Code Online (Sandbox Code Playgroud)

最后,使用上面所有库实现咖啡研磨机的类库(我喜欢咖啡!)

using Logging;
using LibraryA;

namespace Coffee
{
    public interface ICoffeeGrinder
    {
        GrindCoffee(int grams);
    }

    public class CoffeeGrinder : ICoffeeGrinder
    {
        readonly ILogger _logger;
        readonly IServiceA _serviceA;
        readonly IServiceB _serviceB;

        public CoffeeGrinder(ILoggerFactory loggerFactory, string loggerName,
            IServiceA serviceA, IServiceB serviceB)
        {
            _logger = loggerFactory.CreateLogger(loggerName);
            _serviceA = serviceA;
            _serviceB = serviceB;
        }

        public GrindCoffee(int grams)
        {
            _logger.Info($"About to grind {grams}g of coffee...");
            // Grind coffee
            _logger.Info("Done grinding.");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

根据(例如)配置文件,应用程序可能需要多个研磨机,每个研磨机都有自己的名称.

因此,我希望能够loggerName在解决时间指定,如下所示:

using Coffee;
using DryIoC;
using LibraryA;
using Logging;
using Logging.Console;

namespace MyApplication
{
    class Program
    {
        static void Main()
        {
            using (var container = new Container())
            {
                container.Register<ILoggerFactory, ConsoleLoggerFactory>();
                container.Register<IServiceA, ServiceA>();
                container.Register<IServiceB, ServiceB>();
                container.Register<ICoffeeGrinder, CoffeeGrinder>(
                    /* Maybe some magic here? */);

                // This won't work
                var grinder = container.Resolve<ICoffeeGrinder>("My grinder"); 
                // Use grinder
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

换句话说,如何告诉DryIoC一个或多个构造函数参数不是依赖项,而是必须在解析时指定?

dad*_*dhi 7

解析为Func<string, ICoffeeGrinder>,这不是主要容器支持的不常见功能,例如Autofac.这是关于这个主题的 DryIoc wiki .

var getGrinder = container.Resolve<Func<string, ICoffeeGrinder>>();
var grinder = getGrinder(name);
Run Code Online (Sandbox Code Playgroud)

顺便说一句,您可以查看许多IoC/DI容器的主要功能列表以节省您的时间.此基本链接也可在基准测试下的DryIoc自述文件中找到.

  • 非常感谢@dadhi!这正是我一直在寻找的。我不知道当我阅读文档时它是如何逃脱的(因为是的,我确实阅读了它)。可能是信息溢出。啊,我老了……:-) (2认同)