gpt4 book ai didi

c# - 使用 Ninject(或其他一些容器)我如何找出请求服务的类型?

转载 作者:行者123 更新时间:2023-11-30 14:20:51 26 4
gpt4 key购买 nike

假设我有一个服务接口(interface):

public interface IFooService
{
void DoSomething();
}

以及通用服务的具体实现:

public class FooService<TRequestingClass> : IFooService
{
public virtual void DoSomething() { }
}

我还有其他一些需要 IFooService 实例的类:

public class Bar
{
private IFooService _fooService;
public Bar(IFooService fooService)
{
this._fooService = fooService;
}
}

我需要连接我的 IoC 容器,以便在创建 Bar 时向其传递 FooService 的构造函数参数。还有很多其他的类,就像 Bar 一样。每个人可能还需要传递给它们的 FooService 实例,其中 TRequestingClass 是需要 IFooService 实例的类的类型。我不需要向 IFooService 的使用者公开这种古怪之处。他们应该关心的只是他们可以调用传递给他们的 IFooService 的方法。他们不需要知道传递给他们的 IFooService 的具体实现需要构造任何特殊的东西。

FooService 的一个可接受的替代方案是一个非泛型类,它在其构造函数中有一个字符串参数,其中包含为其创建的类的名称。即:

public class FooService : IFooService
{
public FooService(string requestingClassName) { }
}

如何连接我的 IoC 容器以这种方式构建依赖项?

如果您对为什么我想要这样一个奇怪的结构感到困惑,请考虑当您获得一个使用 log4net.LogManager.GetLogger(typeof(SomeClass)) 创建的 ILog 时,log4net 如何工作得最好。我不想在我的代码中引用 log4net,所以我想编写一个简单的 ILogger 接口(interface),并用类似这样的东西实现它:

public class GenericLogger<T> : ILogger
{
private readonly ILog log;

public GenericLogger()
{
this.log = log4net.LogManager.GetLogger(typeof(T));
}

public void Debug(object message)
{
this.log.Debug(message);
}

/* .... etc .... */
}

最佳答案

最简单的方法是创建一个 ILogger<T>接口(interface):

public class ILogger<T> : ILogger { }
public class GenericLogger<T> : ILogger<T> { ... }

然后依靠泛型类型推断得到正确的类型。例如,在 Ninject 中,您只需要以下绑定(bind):

Bind(typeof(ILogger<>)).To(typeof(GenericLogger<>));

那么您的消费类型将如下所示:

public class FooService : IFooService {
public FooService(ILogger<FooService> logger) { ... }
}

如果您坚决反对 ILogger<T>界面,您可以做一些更有创意的事情,比如自定义提供程序,它读取 IContext确定父类型。

public class GenericLogger : ILogger {
public class GenericLogger(Type type) { ... }
}

public class LoggerProvider : Provider<ILogger> {
public override ILogger CreateInstance(IContext context) {
return new GenericLogger(context.Target.Member.ReflectedType);
}
}

然后消费类型会像这样工作:

public class FooService : IFooService {
public FooService(ILogger logger) { ... }
}

关于c# - 使用 Ninject(或其他一些容器)我如何找出请求服务的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/719346/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com