【发布时间】:2017-12-04 22:47:59
【问题描述】:
更新
我用以下代码解决了这个问题,但这不是我正在寻找的解决方案。 对于更通用的解决方案,这仍然是一个开放的赏金。如果我们有一个不是 int 或 string 键值的表,我们将不得不手动添加让它发挥作用。
c.For(typeof(ILogDifferencesCommand<,>)).Use(typeof(LogDifferencesCommand<,>))
.Ctor<ILogDifferencesLogger<int>>()
.Named(AppSettingsManager.Get("logDifferences:Target"))
.Ctor<string>()
.Named(AppSettingsManager.Get("logDifferences:Target"));
原始问题
我有三种类型的记录器,我在容器中为它们定义了命名实例:
c.For(typeof(ILogDifferencesLogger<>))
.Use(typeof(LogDifferencesAllLogger<>))
.Named("all");
c.For(typeof(ILogDifferencesLogger<>))
.Use(typeof(LogDifferencesNLogLogger<>))
.Named("nlog");
c.For(typeof(ILogDifferencesLogger<>))
.Use(typeof(LogDifferencesDatabaseLogger<>))
.Named("database");
LogDifferencesCommand 接收 ILogDifferencesLogger<> 作为其唯一参数:
public LogDifferencesCommand(ILogDifferencesLogger<TKey> logDifferencesLogger)
{
this.logDifferencesLogger = logDifferencesLogger;
}
如何正确配置ILogDifferencesCommand<> 以根据应用程序设置获取正确的命名实例?现在我有这样的东西:
c.For(typeof(ILogDifferencesCommand<,>))
.Use(typeof(LogDifferencesCommand<,>));
我遇到的问题是我无法引入Ctor<>,因为我不能使用带有该签名的未绑定泛型,所以我不能使用Ctor 之外的Named 方法那个。
例如,我可以做这样的事情,但这不会影响所有可能的类型:
c.For(typeof(ILogDifferencesCommand<,>)).Use(typeof(LogDifferencesCommand<,>))
.Ctor<ILogDifferencesLogger<int>>()
.Named(AppSettingsManager.Get("logDifferences:Target"));
但问题是我必须处理系统使用的每个TKey 类型。
类和接口定义
public class LogDifferencesCommand<TModel, TKey> : ILogDifferencesCommand<TModel, TKey>
where TModel : class, IIdModel<TKey>
{
public LogDifferencesCommand(ILogDifferencesLogger<TKey> logDifferencesLogger)
{
this.logDifferencesLogger = logDifferencesLogger;
}
}
public interface ILogDifferencesCommand<TModel, TKey>
where TModel : class, IIdModel<TKey>
{
List<LogDifference> CalculateDifferences(TModel x, TModel y);
void LogDifferences(TModel x, TModel y, string tableName, string keyField, string userId, int? clientId);
void RegisterCustomDisplayNameObserver(WeakReference<ICustomDisplayNameObserver<TModel>> observer);
void RegisterCustomChangeDateObserver(WeakReference<ICustomChangeDateObserver<TModel>> observer);
}
public interface ILogDifferencesLogger<TKey>
{
void LogDifferences(string tableName, string keyField, string userId, TKey id, List<LogDifference> differences, int? clientId);
}
之所以需要TKey,是因为IIdModel接口。
【问题讨论】:
-
嗯,我觉得你有点想多了。只需创建 ILoggerFactory 并通过一些“创建”方法实例化您的 ILogDifferencesCommand。说真的,为了简单起见——它比 raping DI 框架更具可读性。无论哪种方式,您都使用 conventions 来实现这种反射。
-
@eocron 我知道你来自哪里。但是,这允许我们使用 DI 来获取实例,而不必在众多构造函数中添加调用。它使我们的课程非常简洁和一致。
标签: c# .net generics dependency-injection structuremap