рд╡рд┐рдВрдбреЛрдЬ рдлреЛрди + Caliburn.Micro + рдСрдЯреЛрдлреЗрдХ

рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рд╡рд┐рдВрдбреЛрдЬ рдлреЛрди рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рд╣реИред рдореБрдЭреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдорд╡реАрд╡реАрдПрдо рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдФрд░ рдЖрдИрдУрд╕реА рдХрдВрдЯреЗрдирд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбрдмреНрд▓реНрдпреВрдкреАрдПрдл рдФрд░ рд╕рд┐рд▓реНрд╡рд░рд▓рд╛рдЗрдЯ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд╕рд┐рдд рд╣реЛрдиреЗ рдХрд╛ рдХреБрдЫ рдЕрдиреБрднрд╡ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рдХрд╛рд░реНрдп рдореЗрд░реЗ рд▓рд┐рдП рдмрд╣реБрдд рдореБрд╢реНрдХрд┐рд▓ рдирд╣реАрдВ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдирд┐рдХрд▓рд╛, рдореЗрд░рд╛ рдкрд╕рдВрджреАрджрд╛ Caliburn.Micro MVVM рдлреНрд░реЗрдорд╡рд░реНрдХ (CM) рдФрд░ рдореЗрд░рд╛ рдкрд╕рдВрджреАрджрд╛ Autofac IoC рдХрдВрдЯреЗрдирд░ рдЗрд╕ рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЕрдкрдиреА рдЖрд╕реНрддреАрдиреЗрдВ рдЙрддрд╛рд░реАрдВ рдФрд░ рдЖрд╡реЗрджрди рдХреЗ рдХрдВрдХрд╛рд▓ рдмрдирд╛рдиреЗ рд╢реБрд░реВ рдХрд┐рдПред CM рдЕрдкрдиреЗ рдХрд╛рдо рдХреЗ рд▓рд┐рдП IoC рдХрдВрдЯреЗрдирд░ рдХрд╛ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдЖрдк рдпрд╛ рддреЛ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХрдВрдЯреЗрдирд░ (рд╕рд┐рдВрдкрд▓рдХреЙрдирдЯреЗрдирд░) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдХрдИ рдЕрдиреНрдп рдЬрд┐рдирдХреЗ рд▓рд┐рдП рд╕реАрдПрдо рдХреЗ рд▓рд┐рдП рдПрдбреЗрдкреНрдЯрд░ рд╣реИрдВред рдСрдЯреЛрдлрд╛рдХ рдХреЗ рд▓рд┐рдП рдРрд╕рд╛ рдПрдХ рдПрдбреЗрдкреНрдЯрд░ рд╣реИ - рдХреИрд▓рд┐рдмрд░реНрдиред рдПрдорд┐рдХреНрд░реЛ.рдСрдЯреЛрдлреИрдХ , рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдбрдмреНрд▓реНрдпреВрдкреАрдПрдл рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдерд╛ред рдпрд╣ рдЕрджреНрднреБрдд рд╣реИ, рд▓реЗрдХрд┐рди рдЯрд╛рд░ рдмреИрд░рд▓, рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдорд░рд╣рдо рдореЗрдВ рдПрдХ рдордХреНрдЦреА рджреНрд╡рд╛рд░рд╛ рдмрд░реНрдмрд╛рдж рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ - рд╕реАрдПрдо 1.3.1 (рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг) рдХреЗ рд▓рд┐рдП рдСрдЯреЛрдлрд╛рдХ рдПрдбрд╛рдкреНрдЯрд░ рд╡рд┐рдВрдбреЛрдЬ рдлреЛрди рдХреЗ рддрд╣рдд рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдХреБрдЫ рд╕рдордп рдкрд╣рд▓реЗ рддрдХ, рдпрд╣ рд╕рдВрдХрд▓рди рднреА рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рд▓реЗрдЦрдХ, рдбреЗрд╡рд┐рдб рдмрдХреНрд╕рдмрд╛рдЙрдо рдиреЗ рд▓рдЧрднрдЧ рддреАрди рд╕рдкреНрддрд╛рд╣ рдкрд╣рд▓реЗ рдЗрд╕ рджреЛрд╖ рдХреЛ рдареАрдХ рдХрд┐рдпрд╛ рдерд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХ рддрд░реАрдХрд╛ рдпрд╛ рдХреЛрдИ рдЕрдиреНрдп, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛рдо рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдЬрд╛рд╣рд┐рд░рд╛ рддреМрд░ рдкрд░ рдбреЗрд╡рд┐рдб рдЦреБрдж рд╡рд┐рдВрдбреЛрдЬ рдлреЛрди рдХреЗ рд▓рд┐рдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╡рд┐рдХрд╕рд┐рдд рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдпрд╣ рд╕рдВрд╕реНрдХрд░рдг рдЕрдзреВрд░рд╛ рд░рд╣ рдЧрдпрд╛ рд╣реИред рдореИрдВ рдЕрдкрдиреЗ рдкрд╕рдВрджреАрджрд╛ рдмрдВрдбрд▓ рдХреЛ рдордирд╛ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛ рдФрд░ рдореБрдЭреЗ рдЗрд╕ рдПрдбреЙрдкреНрдЯрд░ рдХреЛ рдЦреБрдж рд▓рд┐рдЦрдирд╛ рдерд╛ред рдЖрдЬ рдореИрдВ рдЖрдкрдХреЗ рдзреНрдпрд╛рди рдореЗрдВ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реВрдВред

рдореБрдЭреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдирд╛ рдерд╛:


AutofacBootstrapper рдФрд░ AutofacPhoneContainer рдХреЗ рдЕрдВрддрд┐рдо рд╕рдВрд╕реНрдХрд░рдг рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рд╣реИрдВ, рдореИрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдХреБрдЫ рд╕рдордп рдкрд╣рд▓реЗ рд▓реЗрдЦрдХ рдХреЛ рднреЗрдЬрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдХрд┐рд╕реА рдХрд╛рд░рдг рд╕реЗ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЙрдиреНрд╣реЗрдВ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдПрдХреАрдХреГрдд рдирд╣реАрдВ рдХрд┐рдпрд╛, рдмрд╕ рдПрдХ рдЯреВрдЯрд╛ рд╣реБрдЖ рд╕рдВрд╕реНрдХрд░рдг рд╣реИ (рдбреЗрдЯрд╛ рдХреЛ рдЕрд▓рдЧ рднрдВрдбрд╛рд░рдг рдФрд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╕рд╣реЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП)ред рдкрд░реАрдХреНрд╖рдг рдкрд░рд┐рдпреЛрдЬрдирд╛ рдпрд╣рд╛рдВ рд╕реЗ рдбрд╛рдЙрдирд▓реЛрдб рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ ред
рд╕рд╛рде рд╣реА, рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдореБрдЭреЗ рд╕реАрдПрдо рдХреЗ рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдПрдХ рдЕрдкреНрд░рд┐рдп рдмрдЧ рдорд┐рд▓рд╛: рдЕрд▓рдЧ-рдЕрд▓рдЧ рднрдВрдбрд╛рд░рдг рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдлрд╝реАрд▓реНрдб рдХреЗ рдорд╛рди рд╕рднреА рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдореЗрдВ рд╕рд╣реЗрдЬреЗ рдирд╣реАрдВ рдЬрд╛рддреЗ рд╣реИрдВред рдореЗрд░реЗ рдЯреЗрд╕реНрдЯ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ рдмрд┐рд▓реНрдб CM рдкрд╣рд▓реЗ рд╣реА рдЗрд╕ рдЦрд╛рдореА рдХреЛ рдмрдЦреНрд╢ рдЪреБрдХрд╛ рд╣реИред рдореИрдВрдиреЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реБрдП CM рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рдПрдХ рдмрдЧ рд░рд┐рдкреЛрд░реНрдЯ рдмрдирд╛рдИред рдЖрд╢рд╛ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕реЗ рдЬрд▓реНрдж рд╣реА рдареАрдХ рдХрд░ рд▓рд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдСрдЯреЛрдлреИрдХ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд░
// Project: Caliburn.Micro.Autofac // File name: AutofacBootstrapper.cs // File GUID: C5C743E2-7AD1-496C-824A-9AEFBF5F8979 // Authors: David Buksbaum (david@buksbaum.us), Mike Eshva (mike@eshva.ru) // Date of creation: 20.05.2012 using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection; using System.Windows.Controls; using Autofac; using Microsoft.Phone.Controls; using IContainer = Autofac.IContainer; namespace Caliburn.Micro.Autofac { /// <summary> /// Autofac specific <see cref="PhoneBootstrapper"/> realization. /// </summary> public class AutofacBootstrapper : PhoneBootstrapper { #region Public properties /// <summary> /// Gets or sets flag should the namespace convention be enforced for type registration. The /// default is true. For views, this would require a views namespace to end with Views For /// view-models, this would require a view models namespace to end with ViewModels. /// </summary> /// <remarks> /// Case is important as views would not match. /// </remarks> public bool EnforceNamespaceConvention { get; set; } /// <summary> /// Gets or sets flag should the view be treated as loaded when registering the /// <see cref="INavigationService"/>. /// </summary> public bool TreatViewAsLoaded { get; set; } /// <summary> /// Gets or sets the base type required for a view model. /// </summary> public Type ViewModelBaseType { get; set; } /// <summary> /// Gets or sets method for creating the window manager. /// </summary> public Func<IWindowManager> CreateWindowManager { get; set; } /// <summary> /// Gets or sets method for creating the event aggregator. /// </summary> public Func<IEventAggregator> CreateEventAggregator { get; set; } /// <summary> /// Gets or sets method for creating the frame adapter. /// </summary> public Func<FrameAdapter> CreateFrameAdapter { get; set; } /// <summary> /// Gets or sets method for creating the phone application service adapter. /// </summary> public Func<PhoneApplicationServiceAdapter> CreatePhoneApplicationServiceAdapter { get; set; } /// <summary> /// Gets or sets method for creating the vibrate controller. /// </summary> public Func<IVibrateController> CreateVibrateController { get; set; } /// <summary> /// Gets or sets method for creating the sound effect player. /// </summary> public Func<ISoundEffectPlayer> CreateSoundEffectPlayer { get; set; } #endregion #region Protected interface /// <summary> /// Gets Autofac container instance. /// </summary> protected IContainer Container { get; private set; } /// <summary> /// Do not override this method. This is where the IoC container is configured. /// </summary> /// <exception cref="NullReferenceException"> /// Either CreateFrameAdapter or CreateWindowManager or CreateEventAggregator or /// CreatePhoneApplicationServiceAdapter or CreateVibrateController or /// CreateSoundEffectPlayer is null. /// </exception> protected override void Configure() { // allow base classes to change bootstrapper settings ConfigureBootstrapper(); // validate settings if (CreateFrameAdapter == null) { throw new NullReferenceException("CreateFrameAdapter is not specified."); } if (CreateWindowManager == null) { throw new NullReferenceException("CreateWindowManager is not specified."); } if (CreateEventAggregator == null) { throw new NullReferenceException("CreateEventAggregator is not specified."); } if (CreatePhoneApplicationServiceAdapter == null) { throw new NullReferenceException( "CreatePhoneApplicationServiceAdapter is not specified."); } if (CreateVibrateController == null) { throw new NullReferenceException("CreateVibrateController is not specified."); } if (CreateSoundEffectPlayer == null) { throw new NullReferenceException("CreateSoundEffectPlayer is not specified."); } // Configure container. ContainerBuilder lBuilder = new ContainerBuilder(); // Register phone services. Assembly lCaliburnAssembly = typeof (IStorageMechanism).Assembly; // Register IStorageMechanism implementors. lBuilder.RegisterAssemblyTypes(lCaliburnAssembly) .Where( aType => typeof (IStorageMechanism).IsAssignableFrom(aType) && !aType.IsAbstract && !aType.IsInterface) .As<IStorageMechanism>() .InstancePerLifetimeScope(); // Register IStorageHandler implementors. lBuilder.RegisterAssemblyTypes(AssemblySource.Instance.ToArray()) .Where( aType => typeof (IStorageHandler).IsAssignableFrom(aType) && !aType.IsAbstract && !aType.IsInterface) .As<IStorageHandler>() .InstancePerLifetimeScope(); // Register view models. lBuilder.RegisterAssemblyTypes(AssemblySource.Instance.ToArray()) // Must be a type with a name that ends with ViewModel. .Where(aType => aType.Name.EndsWith("ViewModel")) // Mmust be in a namespace ending with ViewModels. .Where( aType => !EnforceNamespaceConvention || (!string.IsNullOrEmpty(aType.Namespace) && aType.Namespace.EndsWith("ViewModels"))) // Must implement INotifyPropertyChanged (deriving from PropertyChangedBase will statisfy this). .Where(aType => aType.GetInterface(ViewModelBaseType.Name, false) != null) // Registered as self. .AsSelf() // Subscribe on Activated event for viewmodels to make storage mechanism work. .OnActivated(aArgs => ActivateInstance(aArgs.Instance)) // Always create a new one. .InstancePerDependency(); // Register views. lBuilder.RegisterAssemblyTypes(AssemblySource.Instance.ToArray()) // Must be a type with a name that ends with View. .Where(aType => aType.Name.EndsWith("View")) // Must be in a namespace that ends in Views. .Where( aType => !EnforceNamespaceConvention || (!string.IsNullOrEmpty(aType.Namespace) && aType.Namespace.EndsWith("Views"))) // Registered as self. .AsSelf() // Always create a new one. .InstancePerDependency(); // Register the singletons. lBuilder.Register<IPhoneContainer>( aContext => new AutofacPhoneContainer(aContext.Resolve<IComponentContext>())) .SingleInstance(); lBuilder.RegisterInstance<INavigationService>(CreateFrameAdapter()) .SingleInstance(); PhoneApplicationServiceAdapter lPhoneService = CreatePhoneApplicationServiceAdapter(); lBuilder.RegisterInstance<IPhoneService>(lPhoneService) .SingleInstance(); lBuilder.Register(aContext => CreateEventAggregator()) .SingleInstance(); lBuilder.Register(aContext => CreateWindowManager()) .SingleInstance(); lBuilder.Register(aContext => CreateVibrateController()) .SingleInstance(); lBuilder.Register(aContext => CreateSoundEffectPlayer()) .SingleInstance(); lBuilder.RegisterType<StorageCoordinator>().AsSelf() .SingleInstance(); lBuilder.RegisterType<TaskController>().AsSelf() .SingleInstance(); // Allow derived classes to add to the container. ConfigureContainer(lBuilder); // Build the container Container = lBuilder.Build(); // Get the phone container instance. PhoneContainer = (AutofacPhoneContainer) Container.Resolve<IPhoneContainer>(); // Start the storage coordinator. StorageCoordinator lStorageCoordinator = Container.Resolve<StorageCoordinator>(); lStorageCoordinator.Start(); // Start the task controller. TaskController lTaskController = Container.Resolve<TaskController>(); lTaskController.Start(); // Add custom conventions for the phone. AddCustomConventions(); } /// <summary> /// Do not override unless you plan to full replace the logic. This is how the framework /// retrieves services from the Autofac container. /// </summary> /// <param name="aService"> /// The service to locate. /// </param> /// <param name="aKey"> /// The key to locate. /// </param> /// <returns> /// The located service. /// </returns> /// <exception cref="Exception"> /// Could not locate any instances of service. /// </exception> protected override object GetInstance(Type aService, string aKey) { object lInstance; if (string.IsNullOrEmpty(aKey)) { if (Container.TryResolve(aService, out lInstance)) { return lInstance; } } else { if (Container.TryResolveNamed(aKey, aService, out lInstance)) { return lInstance; } } throw new Exception( string.Format( "Could not locate any instances of service {0}.", aKey ?? aService.Name)); } /// <summary> /// Do not override unless you plan to full replace the logic. This is how the framework /// retrieves services from the Autofac container. /// </summary> /// <param name="aService"> /// The service to locate. /// </param> /// <returns> /// The located services. /// </returns> protected override IEnumerable<object> GetAllInstances(Type aService) { IEnumerable<object> lResult = Container.Resolve(typeof (IEnumerable<>).MakeGenericType(aService)) as IEnumerable<object>; return lResult; } /// <summary> /// Do not override unless you plan to full replace the logic. This is how the framework /// retrieves services from the Autofac container. /// </summary> /// <param name="aInstance"> /// The instance to perform injection on. /// </param> protected override void BuildUp(object aInstance) { Container.InjectProperties(aInstance); } /// <summary> /// Override to provide configuration prior to the Autofac configuration. You must call the base version BEFORE any /// other statement or the behaviour is undefined. /// Current Defaults: /// EnforceNamespaceConvention = true /// TreatViewAsLoaded = false /// ViewModelBaseType = <see cref="System.ComponentModel.INotifyPropertyChanged"/> /// CreateWindowManager = <see cref="Caliburn.Micro.WindowManager"/> /// CreateEventAggregator = <see cref="Caliburn.Micro.EventAggregator"/> /// CreateFrameAdapter = <see cref="Caliburn.Micro.FrameAdapter"/> /// CreatePhoneApplicationServiceAdapter = <see cref="Caliburn.Micro.PhoneApplicationServiceAdapter"/> /// CreateVibrateController = <see cref="Caliburn.Micro.SystemVibrateController"/> /// CreateSoundEffectPlayer = <see cref="Caliburn.Micro.XnaSoundEffectPlayer"/> /// </summary> protected virtual void ConfigureBootstrapper() { // By default, enforce the namespace convention. EnforceNamespaceConvention = true; // By default, do not treat the view as loaded. TreatViewAsLoaded = false; // The default view model base type. ViewModelBaseType = typeof (INotifyPropertyChanged); // Default window manager. CreateWindowManager = () => new WindowManager(); // Default event aggregator. CreateEventAggregator = () => new EventAggregator(); // Default frame adapter. CreateFrameAdapter = () => new FrameAdapter(RootFrame, TreatViewAsLoaded); // Default phone application service adapter. CreatePhoneApplicationServiceAdapter = () => new PhoneApplicationServiceAdapter(RootFrame); // Default vibrate controller. CreateVibrateController = () => new SystemVibrateController(); // Default sound effect player. CreateSoundEffectPlayer = () => new XnaSoundEffectPlayer(); } /// <summary> /// Override to include your own Autofac configuration after the framework has finished its /// configuration, but before the container is created. /// </summary> /// <param name="aBuilder"> /// The Autofac configuration builder. /// </param> protected virtual void ConfigureContainer(ContainerBuilder aBuilder) { } /// <summary> /// Activates an instance in phone container. Derived types should call this method for /// registering types that should support storage mechanism. /// </summary> /// <param name="aInstance"> /// Instance to activate. /// </param> /// <remarks> /// Use this method as event handler on service registation in /// <see cref="ConfigureContainer"/> method. ViewModels already registering with using it. /// </remarks> protected void ActivateInstance(object aInstance) { if (PhoneContainer == null) { return; } PhoneContainer.ActivateInstance(aInstance); } #endregion #region Private properties private AutofacPhoneContainer PhoneContainer { get; set; } #endregion #region Private methods private static void AddCustomConventions() { ConventionManager.AddElementConvention<Pivot>( ItemsControl.ItemsSourceProperty, "SelectedItem", "SelectionChanged").ApplyBinding = (aViewModelType, aPath, aProperty, aElement, aConvention) => { if (ConventionManager .GetElementConvention(typeof (ItemsControl)) .ApplyBinding(aViewModelType, aPath, aProperty, aElement, aConvention)) { ConventionManager .ConfigureSelectedItem( aElement, Pivot.SelectedItemProperty, aViewModelType, aPath); ConventionManager .ApplyHeaderTemplate( aElement, Pivot.HeaderTemplateProperty, null, aViewModelType); return true; } return false; }; ConventionManager.AddElementConvention<Panorama>( ItemsControl.ItemsSourceProperty, "SelectedItem", "SelectionChanged").ApplyBinding = (aViewModelType, aPath, aProperty, aElement, aConvention) => { if (ConventionManager .GetElementConvention(typeof (ItemsControl)) .ApplyBinding(aViewModelType, aPath, aProperty, aElement, aConvention)) { ConventionManager .ConfigureSelectedItem( aElement, Panorama.SelectedItemProperty, aViewModelType, aPath); ConventionManager .ApplyHeaderTemplate( aElement, Panorama.HeaderTemplateProperty, null, aViewModelType); return true; } return false; }; } #endregion } } 



рдСрдЯреЛрдлреИрдХ рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд░
 // Project: Caliburn.Micro.Autofac // File name: AutofacBootstrapper.cs // File GUID: CB807DF7-2D69-4B05-AC17-C3E191D7C182 // Authors: Mike Eshva (mike@eshva.ru) // Date of creation: 20.05.2012 using System; using System.IO.IsolatedStorage; using Autofac; namespace Caliburn.Micro.Autofac { /// <summary> /// Component that allows storage system to communicate with Autofac IoC container. /// </summary> public class AutofacPhoneContainer : IPhoneContainer { #region Constructors /// <summary> /// Initialize new instance of component that allows storage system to communicate with /// Autofac IoC container. /// </summary> /// <param name="aContext"> /// Autofac IoC context. /// </param> /// <exception cref="ArgumentNullException"> /// Autofac IoC context not specified. /// </exception> public AutofacPhoneContainer(IComponentContext aContext) { if (aContext == null) { throw new ArgumentNullException("aContext", "Autofac IoC context is not specified."); } Context = aContext; } #endregion #region IPhoneContainer Members /// <summary> /// Registers the service as a singleton stored in the phone state. /// </summary> /// <param name="aService"> /// The service. /// </param> /// <param name="aPhoneStateKey"> /// The phone state key. /// </param> /// <param name="aImplementation"> /// The implementation. /// </param> public void RegisterWithPhoneService (Type aService, string aPhoneStateKey, Type aImplementation) { string lObjectKey = aPhoneStateKey ?? aService.FullName; IPhoneService lPhoneService = Context.Resolve<IPhoneService>(); if (!lPhoneService.State.ContainsKey(lObjectKey)) { // There is no object with such a key in the phone state. // Create a plain new object and store it the phone state. object lEntireGraphObject = Context.Resolve(aService); lPhoneService.State[lObjectKey] = lEntireGraphObject; // Effectively replace service registration in // Autofac-container (the last registration wins). ContainerBuilder lBuilder = new ContainerBuilder(); lBuilder.RegisterType(aImplementation) .As(aService) .OnActivating( // Replace an object build by the container with one // from the phone state using OnActivating event. aArgs => { IPhoneService lInnerPhoneService = aArgs.Context.Resolve<IPhoneService>(); if (lInnerPhoneService.State.ContainsKey(lObjectKey)) { object lInstance = lInnerPhoneService.State[lObjectKey]; aArgs.ReplaceInstance(lInstance); } }); lBuilder.Update(Context.ComponentRegistry); } } /// <summary> /// Registers the service as a singleton stored in the app settings. /// </summary> /// <param name="aService"> /// The service. /// </param> /// <param name="aPhoneSettingsKey"> /// The app settings key. /// </param> /// <param name="aImplementation"> /// The implementation. /// </param> /// <exception cref="ArgumentNullException"> /// Service or implementation not specified. /// </exception> public void RegisterWithAppSettings (Type aService, string aPhoneSettingsKey, Type aImplementation) { string lObjectKey = aPhoneSettingsKey ?? aService.FullName; if (!IsolatedStorageSettings.ApplicationSettings.Contains(lObjectKey)) { // There is no object with such a key in the application isolated storage. // Probably it is the first time application executed. // Create a plain new object and store it the application isolated storage. object lEntireGraphObject = Context.Resolve(aImplementation); IsolatedStorageSettings.ApplicationSettings[lObjectKey] = lEntireGraphObject; } // Effectively replace service registration in // Autofac-container (the last registration wins). ContainerBuilder lBuilder = new ContainerBuilder(); lBuilder.RegisterType(aImplementation) .As(aService) .OnActivating( // Replace an object build by the container with one // from the application isolated storage using OnActivating event. aArgs => { if (IsolatedStorageSettings.ApplicationSettings.Contains(lObjectKey)) { object lInstance = IsolatedStorageSettings.ApplicationSettings[lObjectKey]; aArgs.ReplaceInstance(lInstance); } }); lBuilder.Update(Context.ComponentRegistry); } /// <summary> /// Occurs when a new instance is created. /// </summary> public event Action<object> Activated = delegate { }; #endregion #region Assembly interface /// <summary> /// Activates <paramref name="aInstance"/>. /// </summary> /// <param name="aInstance"> /// Instance to activate. /// </param> internal void ActivateInstance(object aInstance) { Activated(aInstance); } #endregion #region Private properties private IComponentContext Context { get; set; } #endregion } } 



PS рдореИрдВ рдареАрдХ рд╕реЗ рдХрд╣реВрдВрдЧрд╛ рдХрд┐ рдпрд╣ рдореЗрд░реЗ рдмреНрд▓реЙрдЧ рдХреА рдПрдХ рдкреЛрд╕реНрдЯ рд╣реИ, рдФрд░ рдореИрдВ рдирд┐рдпрдо рдХреЗ рдкреБрдирд░реНрдореБрджреНрд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирддрд╛ рд╣реВрдВред рд▓реЗрдХрд┐рди рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдмреНрд▓реЙрдЧ рдХрд╛ рдкреНрд░рдЪрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдФрд░ рдЬреЛ рдЬрд╛рдирдХрд╛рд░реА рдореИрдВ рдЕрдкрдиреЗ рд╡рд┐рдЪрд╛рд░ рдореЗрдВ рд╕рд╛рдЭрд╛ рдХрд░рддрд╛ рд╣реВрдВ, рд╡рд╣ рдХрдИ рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддреА рд╣реИред рдПрдХ рдмрд╣рд╛рдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдпрд╣ рдЧрд┐рдирд╛ рдЬрд╛рдПрдЧрд╛ рдХрд┐ рдореИрдВ рдЕрдкрдиреЗ рдмреНрд▓реЙрдЧ рдХреЗ рд▓рд┐рдВрдХ рдирд╣реАрдВ рджреЗрддрд╛ред

Source: https://habr.com/ru/post/In145583/


All Articles