我有一个静态类,它调用静态Logger类,
e.g
static class DoesStuffStatic
{
public static void DoStuff()
{
try
{
//something
}
catch(Exception e)
{
//do stuff;
Logger.Log(e);
}
}
}
static class Logger
{
public static void Log(Exception e)
{
//do stuff here
}
}
如何将Logger注入静态类?
注意:我已阅读Dependency Injection in .NET with examples?,但这似乎使用了实例记录器。
答案 0 :(得分:32)
您无法注入静态记录器。您必须将其更改为实例记录器(如果可以),或将其包装在实例记录器中(将调用静态)。同样很难向静态类注入任何东西(因为你不以任何方式控制静态构造函数) - 这就是为什么我倾向于将我想要注入的所有对象作为参数传递。
答案 1 :(得分:23)
不一定如此。只要您的静态记录器公开以下方法:
这是一个例子。请参考以下课程:DI:
public class Logger : ILogger
{
public void Log(string stringToLog)
{
Console.WriteLine(stringToLog);
}
}
public interface ILogger
{
void Log(string stringToLog);
}
这是我们需要记录器的静态类:
public static class SomeStaticClass
{
private static IKernel _diContainer;
private static ILogger _logger;
public static void Init(IKernel dIcontainer)
{
_diContainer = dIcontainer;
_logger = _diContainer.Get<ILogger>();
}
public static void Log(string stringToLog)
{
_logger.Log(stringToLog);
}
}
现在,在您的应用程序的全局启动中(在本例中,在我的global.asax.cs中),您可以实例化您的DI容器,然后将其交给您的静态类。
public class Global : Ninject.Web.NinjectHttpApplication
{
protected override IKernel CreateKernel()
{
return Container;
}
static IKernel Container
{
get
{
var standardKernel = new StandardKernel();
standardKernel.Bind<ILogger>().To<Logger>();
return standardKernel;
}
}
void Application_Start(object sender, EventArgs e)
{
SomeStaticClass.Init(Container);
SomeStaticClass.Log("Dependency Injection with Statics is totally possible");
}
并且presto!您现在已经在静态类中使用DI运行了。
希望有人帮助。我正在重新使用一个使用大量静态类的应用程序,我们已经成功使用了一段时间了。
答案 2 :(得分:1)
这是“注入”静态记录器功能的一种非常简单的方法。
public static class Logger
{
private static Action<string, Exception> _logError;
public static bool Initialised;
public static void InitLogger(Action<string, Exception, bool> logError)
{
if(logError == null) return;
_logError = logError
Initialised = true;
}
public static void LogError(string msg, Exception e = null)
{
if (_logError != null)
{
try
{
_logError.Invoke(msg, e);
}
catch (Exception){}
}
else
{
Debug.WriteLine($"LogError() Msg: {msg} Exception: {e}");
}
}
}
public class MainViewModel
{
public MainViewModel()
{
//Inject the logger so we can call it globally from anywhere in the project
Logger.InitLogger(LogError);
}
public void LogError(string msg, Exception e = null)
{
//Implementation of logger
}
}
答案 3 :(得分:0)
我不确定Logger的工作原理,但通常您可以使用 RequestService 来获取您的实例。例如,在抽象类中:
this.HttpContext.RequestServices.GetService(typeof(YOUR_SERVICE));
控制器可以访问HttpContext。
第二种方法是在 Startup 中使用它,你可以这样做:
serviceCollection.AddScoped(typeof(ICmsDataContext), typeof(TDbContext));
其中serviceCollection是dotnet Core中的 IServiceCollection 。
希望它有所帮助。