は周りこの質問への答えではなく、仕事を必要とする誰のために、私はこの記事の作業を延長しましたとにかく良いアイデア。独自のログ・インターフェースを開始します。
public interface ILog<T>
{
void LogError(Exception ex, string message, params object[] args);
void LogInformation(string message, params object[] args);
}
そして、フレームワークへの呼び出しを通過するように実装を追加:
public class Log<T> : ILog<T>
{
private readonly ILogger<T> logger;
public Log(ILogger<T> logger)
{
this.logger = logger;
}
public void LogError(Exception ex, string message, params object[] args) => this.logger.LogError(ex, message, args);
public void LogInformation(string message, params object[] args) => this.logger.LogInformation(message, args);
}
は上を移動する、ロガー工場を包むためのインターフェイスを追加します。
public interface ILogFactory
{
ILog<T> CreateLog<T>();
}
実装:
public class LogFactory : ILogFactory
{
private readonly ILoggerFactory loggerFactory;
public LogFactory()
{
this.loggerFactory = new LoggerFactory();
}
public ILog<T> CreateLog<T>() => new Log<T>(new Logger<T>(this.loggerFactory));
}
これは、Microsoft.Extensions.Logging
名前空間を参照する必要がある唯一の場所です。それ以外の場合は、ILogger<T>
の代わりにILog<T>
を、ILoggerFactory
の代わりにILogFactory
を使用してください。あなたの主なコードで
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton<ILogFactory>(new LogFactory());
あなたはこのLogFactory
を取得し、あなたのクラスの特定のLog<T>
を作成することができます:あなたは、通常、依存関係の代わりにラッパーを注入、LoggerFactory
を注入する場所
public class MyClass
{
public void MyMethod(IServiceCollection serviceCollection)
{
var serviceProvider = serviceCollection.BuildServiceProvider();
var logFactory = this.serviceProvider.GetRequiredService<ILogFactory>();
var log = logFactory.CreateLog<ServiceApplication>();
log.LogInformation("Hello, World!");
}
}
あなたが変えることを想像することができますパラメータは、MyMethod
IServiceCollection
からILogFactory
またはILog<MyClass>
から必要に応じて変更できます。そして - 全体のポイントがある - あなたは今で上記のコードを模擬することができます
[Fact]
public void Test()
{
IServiceCollection serviceCollection = new ServiceCollection();
var mockLog = new Mock<ILog<MyClass>>();
var mockLogFactory = new Mock<ILogFactory>();
mockLogFactory.Setup(f => f.CreateLog<MyClass>()).Returns(mockLog.Object);
serviceCollection.AddSingleton<ILogFactory>(mockLogFactory.Object);
var myClass = new MyClass();
myClass.MyMethod(serviceCollection);
mockLog.Verify(l => l.LogInformation("Hello, World!"), Times.Once);
}
「あなたはあなたのアプリケーション全体でコントロールしていない種類に応じてカップリングを追加し、頻繁に問題と技術的負債のソースになります。」 - Steve Smith
通常、ILoggerをコントローラに注入します。 'ILoggerFactory'を注入する理由は何ですか? –
Win
私はそれを試すことができます。まだ拡張メソッドを使用していないので、まだ失敗しますか? –
それは動作します!注入されたオブジェクトをILoggerに変更すると、 "var mockLogger = new Mock >();" mockLogger.Objectをテストコントローラに渡します。あなたが@Winが回答を投稿した場合、私は受け入れることができます。 –