Prism解析与使用类型解决的工厂接口



我一直在使用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被称为

最新更新