J'ai une classe statique qui appelle une classe statique Logger,
par exemple
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
}
}
Comment puis-je injecter le logger dans ma classe statique?
Remarque: J'ai lu Dependency Injection in .NET avec des exemples? , mais cela semble utiliser un enregistreur d'instance.
Vous ne pouvez pas injecter un enregistreur statique. Vous devez soit le changer en un enregistreur d'instance (si vous le pouvez), soit l'envelopper dans un enregistreur d'instance (qui appellera le statique). De plus, il est assez difficile d'injecter quoi que ce soit dans une classe statique (car vous ne contrôlez en aucun cas le constructeur statique) - c'est pourquoi j'ai tendance à passer tous les objets que je veux injecter en tant que paramètres.
Ce n'est pas nécessairement le cas. Tant que votre enregistreur statique expose une méthode pour:
Voici un exemple. Prenez le cours suivant pour DI:
public class Logger : ILogger
{
public void Log(string stringToLog)
{
Console.WriteLine(stringToLog);
}
}
public interface ILogger
{
void Log(string stringToLog);
}
Et voici notre classe statique qui nécessite un enregistreur:
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);
}
}
Maintenant, dans un démarrage global de votre application (dans ce cas, dans mon global.asax.cs), vous pouvez instancier votre conteneur DI, puis le transférer à votre classe statique.
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");
}
Et hop! Vous êtes maintenant opérationnel avec DI dans vos classes statiques.
J'espère que ça aide quelqu'un. Je suis en train de retravailler une application qui utilise BEAUCOUP de classes statiques, et nous l'utilisons avec succès depuis un moment.
C'est un moyen très simple d '"injecter" la fonctionnalité d'un enregistreur statique.
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
}
}
Je ne sais pas comment fonctionne Logger, mais vous pouvez généralement utiliser RequestService pour obtenir votre instance. Par exemple en classe abstraite:
this.HttpContext.RequestServices.GetService(typeof(YOUR_SERVICE));
Il est possible pour le contrôleur, où vous pouvez accéder à HttpContext.
La deuxième façon est de l’utiliser par exemple dans Startup , où vous pouvez le faire:
serviceCollection.AddScoped(typeof(ICmsDataContext), typeof(TDbContext));
où serviceCollection est IServiceCollection in dotnet Core.
J'espère que ça a aidé.