2

我有一个使用 Caliburn 1.5.2 e Autofac 3.0.2 的 .NET 4.0 WPF 应用程序。

我想使用命令行参数来自定义 IoC 容器的构建。

问题是命令行参数仅在Appplication.OnStartup( linkBootstrapper.Configure ) 可用,并且仅在已调用时才会发生。

我想这样做的原因是因为我在此应用程序中有一些服务(USB 设备通信、Web 服务),我希望能够用模拟实例替换这些服务。这些服务在注册后立即初始化(Autofac 的 AutoActivation 扩展),因此选择使用哪种类型的最佳时机是在容器中注册时。

我正在考虑:

  • 将服务的初始化延迟到应用程序的主视图模型。

  • 将容器配置逻辑分为两个阶段,一个Bootstrapper.ConfigureBootstrapper.OnStartup.

主要的警告是:

  • 视图模型将依赖于服务来初始化它们。
  • 将容器配置分为两部分,我必须寻找依赖解析中的问题。
  • 我认为只在一个地方配置容器会更好。

我还考虑过寻找 Main(string[] args) 并将参数缓存在静态实例中,但是该代码是在 WPF 应用程序中自动生成的,并且对此进行干扰似乎有点过于极端。

我想知道是否有人知道这样做的更好方法。

4

2 回答 2

4
Environment.GetCommandLineArgs()

我只是调用它Bootstrapper.Configure()并检查命令行开关,就这么简单。

于 2013-07-24T12:22:07.903 回答
1

您仍然可以在OnStartup()方法中配置容器,只要您在OnStartup()调用之前不隐式或显式地从容器请求任何这些服务,它就不会给您带来任何问题。

Caliburn.Micro 没有Configure()以任何特殊方式处理该方法。事实上,如果您不为GetInstance(), GetAllInstances() and BuildUp()引导程序中的方法提供覆盖,即使您在方法中正确配置,Caliburn.Micro 也将无法使用在您的容器中注册的任何服务Configure()

编辑:我还想澄清一件事。由于您将在该OnStartup()方法中提供额外的配置,因此您应该从中派生引导程序,BootstrapperBase而不是Bootstrapper<TRootModel>因为后者会自动为您显示您的主视图模型,并且因为该主视图模型可能会使用尚未注册的服务,它可能会导致一些问题,所以我们想控制它何时显示。无论如何,废话不多说,这是您可以使用的:

public class AppBootstrapper : BootstrapperBase
{
     SimpleContainer container;

     public AppBootstrapper()
     {
         Start();
     }

     protected override void Configure()
     {  
         container = new SimpleContainer();
         container.Singleton<IWindowManager, WindowManager>();
         container.Singleton<IEventAggregator, EventAggregator>();
         container.PerRequest<IShell, ShellViewModel>();
     }

     protected override object GetInstance(Type service, string key)
     {
         var instance = container.GetInstance(service, key);
         if (instance != null)
             return instance;
         throw new InvalidOperationException("Could not locate any instances.");
     }

     protected override IEnumerable<object> GetAllInstances(Type service)
     {
         return container.GetAllInstances(service);
     }

     protected override void BuildUp(object instance)
     {
         container.BuildUp(instance);
     }

     protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
     {
         // ######################
         // DO THOSE COMMAND LINE CONFIGURATIONS HERE AND EVERYTHING
         // SHOULD BE JUST FINE.
         // ######################
         DisplayRootViewFor<IShell>();
     }
}
于 2013-07-22T22:14:51.047 回答