2011-12-06 24 views
1

是否有示例,教程或任何顯示如何在Windows Phone上使用Caliburn.Micro.Autofac?如何:Caliburn.Micro.Autofac和Windows Phone

我創建了一個只有Caliburn.Micro的基本應用程序,運行良好。然後我決定使用Caliburn.Micro.Autofac,所以我從Caliburn.Micro.Autofac.AutofacBootstrapper導出了我的Bootstrapper,並在引導程序Configure()方法內部調用了base.Configure()。現在我運行我得到的應用程序「找不到類型'AppBootstrapper'。」例外。

感謝任何幫助。

回答

2

這是我爲WP7項目編寫的引導程序。它基於Caliburn.Micro.Autofac.AutofacBootstrapper,但修復了一些錯誤。

public class AppBootstrapper : PhoneBootstrapper 
{ 
    private IContainer container; 

    protected void ConfigureContainer(ContainerBuilder builder) 
    { 
     // put any custom bindings here 
    } 

    #region Standard Autofac/Caliburn.Micro Bootstrapper 

    protected override void Configure() 
    { 
     // configure container 
     var builder = new ContainerBuilder(); 

     // register phone services 
     var caliburnAssembly = AssemblySource.Instance.Union(new[] { typeof(IStorageMechanism).Assembly }).ToArray(); 
     // register IStorageMechanism implementors 
     builder.RegisterAssemblyTypes(caliburnAssembly) 
      .Where(type => typeof(IStorageMechanism).IsAssignableFrom(type) 
         && !type.IsAbstract 
         && !type.IsInterface) 
      .As<IStorageMechanism>() 
      .SingleInstance(); 

     // register IStorageHandler implementors 
     builder.RegisterAssemblyTypes(caliburnAssembly) 
      .Where(type => typeof(IStorageHandler).IsAssignableFrom(type) 
         && !type.IsAbstract 
         && !type.IsInterface) 
      .As<IStorageHandler>() 
      .SingleInstance(); 

     // The constructor of these services must be called 
     // to attach to the framework properly. 
     var phoneService = new PhoneApplicationServiceAdapter(RootFrame); 
     var navigationService = new FrameAdapter(RootFrame, false); 

     builder.Register<IPhoneContainer>(c => new AutofacPhoneContainer(c)).SingleInstance(); 
     builder.RegisterInstance<INavigationService>(navigationService).SingleInstance(); 
     builder.RegisterInstance<IPhoneService>(phoneService).SingleInstance(); 
     builder.Register<IEventAggregator>(c => new EventAggregator()).SingleInstance(); 
     builder.Register<IWindowManager>(c => new WindowManager()).SingleInstance(); 
     builder.Register<IVibrateController>(c => new SystemVibrateController()).SingleInstance(); 
     builder.Register<ISoundEffectPlayer>(c => new XnaSoundEffectPlayer()).SingleInstance(); 
     builder.RegisterType<StorageCoordinator>().AsSelf().SingleInstance(); 
     builder.RegisterType<TaskController>().AsSelf().SingleInstance(); 

     // allow derived classes to add to the container 
     ConfigureContainer(builder); 

     // build the container 
     container = builder.Build(); 

     // start services 
     container.Resolve<StorageCoordinator>().Start(); 
     container.Resolve<TaskController>().Start(); 

     // add custom conventions for the phone 
     AddCustomConventions(); 
    } 

    protected override object GetInstance(Type service, string key) 
    { 
     object instance; 
     if (string.IsNullOrEmpty(key)) 
     { 
      if (container.TryResolve(service, out instance)) 
       return instance; 
     } 
     else 
     { 
      if (container.TryResolveNamed(key, service, out instance)) 
       return instance; 
     } 
     throw new Exception(string.Format("Could not locate any instances of contract {0}.", key ?? service.Name)); 
    } 

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

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

    private static void AddCustomConventions() 
    { 
     ConventionManager.AddElementConvention<Pivot>(Pivot.ItemsSourceProperty, "SelectedItem", "SelectionChanged").ApplyBinding = 
      (viewModelType, path, property, element, convention) => 
      { 
       if (ConventionManager 
        .GetElementConvention(typeof(ItemsControl)) 
        .ApplyBinding(viewModelType, path, property, element, convention)) 
       { 
        ConventionManager 
         .ConfigureSelectedItem(element, Pivot.SelectedItemProperty, viewModelType, path); 
        ConventionManager 
         .ApplyHeaderTemplate(element, Pivot.HeaderTemplateProperty, viewModelType); 
        return true; 
       } 

       return false; 
      }; 

     ConventionManager.AddElementConvention<Panorama>(Panorama.ItemsSourceProperty, "SelectedItem", "SelectionChanged").ApplyBinding = 
      (viewModelType, path, property, element, convention) => 
      { 
       if (ConventionManager 
        .GetElementConvention(typeof(ItemsControl)) 
        .ApplyBinding(viewModelType, path, property, element, convention)) 
       { 
        ConventionManager 
         .ConfigureSelectedItem(element, Panorama.SelectedItemProperty, viewModelType, path); 
        ConventionManager 
         .ApplyHeaderTemplate(element, Panorama.HeaderTemplateProperty, viewModelType); 
        return true; 
       } 

       return false; 
      }; 
    } 

    #endregion 
} 

編輯我創建Caliburn.Micro.Autofac的叉子和固定在GitHub上的問題。希望拉取請求將被接受,這將成爲主要存儲庫的一部分。

現在,你可以從這裏訪問的引導程序,並AutofacPhoneContainer - https://github.com/distantcam/Caliburn.Micro.Autofac/tree/master/src/Caliburn.Micro.Autofac-WP7

+0

感謝您的回覆。說實話,我沒有機會嘗試你的代碼,但是在你的代碼和原來的Caliburn.Micro.Autofac之間進行了快速比較。不幸的是,我並不完全理解你所指的錯誤以及你所做的改變背後的原因。感謝您是否可以解釋這一點。提前致謝。 – TheBlueSky

+0

確定主要修正是首先創建PhoneApplicationServiceAdapter和FrameAdapter,然後添加到Autofac容器中。如果他們沒有初始化,那麼Caliburn Micro無法正常工作。 –

+0

您是否有更新caliburn micro 1.3和新版本的autofac? Caliburn.Micro.Autofac只是1.2.1 –

-1

我實現了一個正確的版本(在我看來)Caliburn.Micro.Autofac的Windows Phone的。您可以從my blog下載並測試項目。該博文是用俄語發佈的,但您可以在帖子頂部找到ZIP文件的鏈接。代碼太大,無法在這裏發佈,所以請從博客中提取。我已將此發送給David Buksbaum(Caliburn.Micro.Autofac的作者)。希望他很快將其納入他的代碼庫。

UPDATE

什麼是固定的:

  1. 組件實現IPhoneService和INavigationService服務必須在容器註冊之前被實例化。
  2. 實現了IPhoneContainer的組件。沒有它,你不能在Caliburn.Micro中使用Autofac。
+0

你可能想描述你已經修復了什麼,而不是僅僅指你的博客。 – jgauffin