我一直在使用Prism构建应用程序,此应用程序将在未来几年内进行很多操作,以便将其设置为模块化和IOC。在此应用程序中,我目前正在为记录机制实施NLOG。
因为我不想在整个应用程序中添加对nlog的引用,所以我为记录器创建了一个接口
public interface ILog
{
void Log(LogLevel loglevel, string format);
void Log(LogLevel loglevel, string format, params object[] args);
void Log(LogLevel loglevel, Exception exc, string format, params object[] args);
}
我还为工厂创建了一个接口
public interface ILogFactory
{
ILog Initialize(Type type);
}
工厂采用类型参数,可用于创建特定于该类的Logger。现在是我要使用目标类型类实例的ILOG的挑战。
public class ClassA
{
private ILog Logger { get; set;}
public ClassA(Ilog logger)
{
Logger = logger;
}
}
如何将我的iLogFactory连接到棱镜中,以便在使用iLogFactory.Initialize(type)的类别的分辨率上与这种情况类型(classa)一起使用。
因此,在搜索更多网络后,我终于找到了我在寻找的东西这个博客
我必须修改代码的出价以使其不依赖于log4net,这导致了以下代码
构建trackingExtension我们需要知道我们要去的记录器需要创建的位置。
public class BuildTrackingExtension : UnityContainerExtension
{
protected override void Initialize()
{
Context.Strategies.AddNew<BuildTrackingStrategy>(UnityBuildStage.TypeMapping);
}
public static IBuildTrackingPolicy GetPolicy(IBuilderContext context)
{
return context.Policies.Get<IBuildTrackingPolicy>(context.BuildKey, true);
}
public static IBuildTrackingPolicy SetPolicy(IBuilderContext context)
{
IBuildTrackingPolicy policy = new BuildTrackingPolicy();
context.Policies.SetDefault(policy);
return policy;
}
}
public class BuildTrackingStrategy : BuilderStrategy
{
public override void PreBuildUp(IBuilderContext context)
{
var policy = BuildTrackingExtension.GetPolicy(context)
?? BuildTrackingExtension.SetPolicy(context);
policy.BuildKeys.Push(context.BuildKey);
}
public override void PostBuildUp(IBuilderContext context)
{
IBuildTrackingPolicy policy = BuildTrackingExtension.GetPolicy(context);
if ((policy != null) && (policy.BuildKeys.Count > 0))
{
policy.BuildKeys.Pop();
}
}
}
public interface IBuildTrackingPolicy : IBuilderPolicy
{
Stack<object> BuildKeys { get; }
}
public class BuildTrackingPolicy : IBuildTrackingPolicy
{
public BuildTrackingPolicy()
{
BuildKeys = new Stack<object>();
}
public Stack<object> BuildKeys { get; private set; }
}
然后logCreationExtension从我的iLogFactory
创建记录器public class LogCreationExtension : UnityContainerExtension
{
private ILogFactory LogFactory;
private LogCreationStrategy strategy;
public LogCreationExtension(ILogFactory logFactory)
{
LogFactory = logFactory;
}
protected override void Initialize()
{
strategy = new LogCreationStrategy(LogFactory);
Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
}
}
public class LogCreationStrategy : BuilderStrategy
{
public bool IsPolicySet { get; private set; }
private ILogFactory LogFactory;
public LogCreationStrategy(ILogFactory logFactory)
{
LogFactory = logFactory;
}
public override void PreBuildUp(IBuilderContext context)
{
Type typeToBuild = context.BuildKey.Type;
if (typeof(ILog).Equals(typeToBuild))
{
if (context.Policies.Get<IBuildPlanPolicy>(context.BuildKey) == null)
{
Type typeForLog = LogCreationStrategy.GetLogType(context);
IBuildPlanPolicy policy = new LogBuildPlanPolicy(typeForLog, LogFactory);
context.Policies.Set<IBuildPlanPolicy>(policy, context.BuildKey);
IsPolicySet = true;
}
}
}
public override void PostBuildUp(IBuilderContext context)
{
if (IsPolicySet)
{
context.Policies.Clear<IBuildPlanPolicy>(context.BuildKey);
IsPolicySet = false;
}
}
private static Type GetLogType(IBuilderContext context)
{
Type logType = null;
IBuildTrackingPolicy buildTrackingPolicy = BuildTrackingExtension.GetPolicy(context);
if ((buildTrackingPolicy != null) && (buildTrackingPolicy.BuildKeys.Count >= 2))
{
logType = ((NamedTypeBuildKey)buildTrackingPolicy.BuildKeys.ElementAt(1)).Type;
}
else
{
StackTrace stackTrace = new StackTrace();
//first two are in the log creation strategy, can skip over them
for (int i = 2; i < stackTrace.FrameCount; i++)
{
StackFrame frame = stackTrace.GetFrame(i);
logType = frame.GetMethod().DeclaringType;
if (!logType.FullName.StartsWith("Microsoft.Practices"))
{
break;
}
}
}
return logType;
}
}
public class LogBuildPlanPolicy : IBuildPlanPolicy
{
private ILogFactory LogFactory;
public LogBuildPlanPolicy(Type logType, ILogFactory logFactory)
{
LogType = logType;
LogFactory = logFactory;
}
public Type LogType { get; private set; }
public void BuildUp(IBuilderContext context)
{
if (context.Existing == null)
{
ILog log = LogFactory.Initialize(LogType);
context.Existing = log;
}
}
}
使用Unity对其进行接线
//Container.RegisterType<ILogFactory, NLogLogFactory>();
Container.RegisterInstance<ILogFactory>(_LogFactory);
Container.AddNewExtension<BuildTrackingExtension>();
Container.AddNewExtension<LogCreationExtension>();
我正在使用RegisterInstance,因为我正在使用logFactory initializeshell被称为