2016-12-07 128 views
0

我一直在用PRISM構建應用程序,這個應用程序在未來幾年中將會很多,所以它被設置爲模塊化並且考慮到IoC。 在這個應用程序中,我正在爲日誌記錄機制實現Nlog。PRISM解決與使用類型解決的工廠的接口

因爲我不想在我的整個應用程序添加到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(類型類型),在這種情況下的typeof(ClassA的)的決心。

+0

您可以簡單地將ILogFactory作爲依賴注入到ClassA中。類a只是使用恰好是ILog實現的工廠實例。 – Xeun

+0

我目前正在使用它,它的工作原理,但只需要有一個Ilog使得類更簡單 –

+0

是的,我明白你想達到什麼目的,但它不會那樣工作。 您的課程取決於Factory sicne,它不知道如何創建ILogger,但Factory確實如此 - 因此Factory是您班級的依賴項。我認爲你只是在解決這個問題。讓班級依靠工廠,你很好走 – Xeun

回答

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>(); 

我,因爲我使用的是的LogFactory使用RegisterInstance InitializeShell被稱爲前

相關問題