我一直在使用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);
}
工厂采用Type参数,该参数可用于创建特定于该类的记录器。现在迎来挑战,我将使用ILog我希望有一个使用目标类型类的实例。
public class ClassA
{
private ILog Logger { get; set;}
public ClassA(Ilog logger)
{
Logger = logger;
}
}
如何将我的ILogFactory连接到PRISM,以便解决使用Ilog的类,该类使用ILogFactory.Initialize(Type type),在本例中为typeof(ClassA)。
答案 0 :(得分:0)
所以在搜索了更多的网页后,我终于找到了我想要的东西 this blog
我不得不修改代码以使其不依赖于log4net这导致以下代码
我们需要知道BuildTrackingExtension需要知道我们要创建的记录器的位置。
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;
}
}
}
使用统一布线
//Container.RegisterType<ILogFactory, NLogLogFactory>();
Container.RegisterInstance<ILogFactory>(_LogFactory);
Container.AddNewExtension<BuildTrackingExtension>();
Container.AddNewExtension<LogCreationExtension>();
我正在使用RegisterInstance,因为我在调用InitializeShell之前使用了logfactory