DryIoC - 在解析时指定一些构造函数参数
DryIoC - Specifying some constructor parameters at resolve time
我在使用 DryIoC 时遇到了一个相当令人费解的情况。
好的,实际上,这是我第一次使用 IoC 容器,所以我可能只是误解了所有内容:从依赖注入到 IoC 容器,再到 DryIoC 本身。
不过,我作为专业程序员已经有一段时间了,我有不错的谷歌搜索能力,我什至找不到其他人暴露的相似问题。
假设我有一个公开这些接口的class库...
namespace Logging
{
public interface ILogger
{
void Info(string message);
}
public interface ILoggerFactory
{
ILogger CreateLogger(string name);
}
}
...和另一个实现上述接口的 class 库。
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);
}
}
然后是第三个库,里面有我需要的其他东西:
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
}
}
最后,class 库使用上述所有库来实现咖啡研磨机(我爱咖啡!)
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.");
}
}
}
根据(例如)配置文件,一个应用程序可能需要多个研磨机,每个研磨机都有自己的名称。
因此我希望能够在解析时指定 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
}
}
}
}
换句话说,我如何告诉 DryIoC 一个或多个构造函数参数 不是 依赖项,而是必须在解析时指定?
解析为 Func<string, ICoffeeGrinder>
,这是主要容器支持的常见功能,例如Autofac。这是 topic.
上的 DryIoc wiki
var getGrinder = container.Resolve<Func<string, ICoffeeGrinder>>();
var grinder = getGrinder(name);
顺便说一句,您可以查看 major feature list 个 IoC/DI 个容器以节省您的时间。这个 link 也可以在 Benchmarks.
下的 DryIoc 自述文件中找到
我在使用 DryIoC 时遇到了一个相当令人费解的情况。
好的,实际上,这是我第一次使用 IoC 容器,所以我可能只是误解了所有内容:从依赖注入到 IoC 容器,再到 DryIoC 本身。
不过,我作为专业程序员已经有一段时间了,我有不错的谷歌搜索能力,我什至找不到其他人暴露的相似问题。
假设我有一个公开这些接口的class库...
namespace Logging
{
public interface ILogger
{
void Info(string message);
}
public interface ILoggerFactory
{
ILogger CreateLogger(string name);
}
}
...和另一个实现上述接口的 class 库。
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);
}
}
然后是第三个库,里面有我需要的其他东西:
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
}
}
最后,class 库使用上述所有库来实现咖啡研磨机(我爱咖啡!)
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.");
}
}
}
根据(例如)配置文件,一个应用程序可能需要多个研磨机,每个研磨机都有自己的名称。
因此我希望能够在解析时指定 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
}
}
}
}
换句话说,我如何告诉 DryIoC 一个或多个构造函数参数 不是 依赖项,而是必须在解析时指定?
解析为 Func<string, ICoffeeGrinder>
,这是主要容器支持的常见功能,例如Autofac。这是 topic.
var getGrinder = container.Resolve<Func<string, ICoffeeGrinder>>();
var grinder = getGrinder(name);
顺便说一句,您可以查看 major feature list 个 IoC/DI 个容器以节省您的时间。这个 link 也可以在 Benchmarks.
下的 DryIoc 自述文件中找到