C#中如何调用通过StructureMap实例化类的构造函数?
Alright, let's walk through your logging setup step by step, with clear code examples for each component to make the structure easy to follow:
ILogger Interface (Ilogger.cs) This interface defines the core logging contract that any logging implementation must adhere to. It keeps your logging logic decoupled from the specific implementation (like LogHelper), making it easy to swap out loggers later if needed.
public interface ILogger { void LogInfo(string message); void LogError(string message, Exception ex = null); // Add other logging methods as required (e.g., LogDebug, LogWarn) }
LogHelper Implementation This class implements ILogger and handles the actual heavy lifting: creating log files and writing messages to them. It's designed to be instantiated via StructureMap, so we avoid manually newing it up in every class.
public class LogHelper : ILogger { private readonly string _logFilePath; public LogHelper() { // Define the log file location (you could also inject this path for more flexibility) _logFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "application.log"); } public void LogInfo(string message) { WriteLogEntry($"INFO: {DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}"); } public void LogError(string message, Exception ex = null) { var logEntry = $"ERROR: {DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}"; if (ex != null) { logEntry += $"\nException Details: {ex.ToString()}"; } WriteLogEntry(logEntry); } private void WriteLogEntry(string entry) { // Create the log file if it doesn't exist, then append the entry using (var writer = new StreamWriter(_logFilePath, true)) { writer.WriteLine(entry); } } }
To let StructureMap handle instantiating LogHelper whenever ILogger is requested, you need to register the dependency mapping at your application's startup. This tells StructureMap which concrete class to use when resolving the interface.
var container = new Container(config => { // Register that any request for ILogger should be fulfilled with a LogHelper instance config.For<ILogger>().Use<LogHelper>(); });
Dummy1 Instead of manually instantiating LogHelper in your class constructors (which creates tight coupling), you should use constructor injection. StructureMap will automatically pass the LogHelper instance to Dummy1 when the class is created.
public class Dummy1 { private readonly ILogger _logger; // Constructor injection: StructureMap provides the LogHelper instance here public Dummy1(ILogger logger) { _logger = logger; // Log initialization when the class is created _logger.LogInfo("Dummy1 class has been initialized successfully."); } // Example method using the logger public void PerformTask() { try { // Execute task logic here _logger.LogInfo("Dummy1 is performing its assigned task."); } catch (Exception ex) { _logger.LogError("Task failed in Dummy1", ex); } } }
Quick Benefits of This Setup
- Decoupling: You can swap
LogHelperfor another logging implementation (like Serilog or NLog) later without changing code inDummy1or other consumer classes. - Testability: You can mock
ILoggerin unit tests forDummy1to avoid writing actual log files during testing. - Centralized Lifecycle Management: StructureMap handles how
LogHelperinstances are created (e.g., singleton, transient), so you don't have to manage this logic in every class.
内容的提问来源于stack exchange,提问作者Gopal Chandak

