ãç´æï¼Windows 8 CPæç¹ã®å 容ã§ããæ£å¼çã§ã¯å¤ãã£ã¦ãããããã¾ããã
WinRTã®MEFã£ã¦CompositionContainerã¯ã©ã¹ãããªããªã£ã¦CompositionServiceã¯ã©ã¹ã§SatisfyImportsOnceã¡ã½ãã使ã£ã¦å¯¾è±¡ã¯ã©ã¹ã«ä½ããImportããã¨ãããã¨ããã§ããªãã£ã½ãã§ãããªã®ã§MVVM Light 4ã®DIã³ã³ããã«MEF使ã£ã¦ãããã¨æã£ãããããªãæ«æãã¦ãã¾ãã¾ããorz
ãããããæããã®ã§ãç¡çããCompositionServiceã¯ã©ã¹ã使ã£ãç¶æ ã§IServiceLocatorã¤ã³ã¿ã¼ãã§ã¼ã¹ãå®è£ ãã¦ã¿ã¾ãããã¡ãªã¿ã«MVVM Light 4ã«æ·»ä»ããã¦ãMicrosoft.Practices.ServiceLocation.dllã使ãã¾ãã
å®è£
ã¨ãããã¨ã§ããã£ã¨å®è£ ãã¦ã¿ã¾ãããSatisfyImportsOnceã¡ã½ããã«RegistrationBuilderã®ã¤ã³ã¹ã¿ã³ã¹ã渡ãã°å®è¡æã«Importã®æåã¨ããããããã¿ãããªã®ã§ãããã使ã£ã¦ãã«ããã«ãã£ã¨ãã¦ã¾ãã
namespace SampleImplementation { using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.ComponentModel.Composition.Primitives; using System.ComponentModel.Composition.Registration; using System.Linq; using System.Reflection; using Microsoft.Practices.ServiceLocation; public class MefServiceLocator : IServiceLocator { private CompositionService service; public MefServiceLocator(params ComposablePartCatalog[] catalogs) { // ã«ã¿ãã°ããCompositionServiceãä½æ var catalog = new AggregateCatalog(catalogs); this.service = catalog.CreateCompositionService(); } private IEnumerable<object> DoGetAllInstances(Type serviceType) { // ManyValueHolder<T>åãä½æ var holderType = typeof(ManyValueHolder<>).MakeGenericType(serviceType); // Valuesããããã£ã«ImportManyãã¤ãã¦ãã¤ã¡ã¼ã¸ var b = new RegistrationBuilder(); b.ForType(holderType) .ImportProperties(p => true, (p, c) => c.AsMany(true)); // ManyValueHolder<T>åã®ã¤ã³ã¹ã¿ã³ã¹ãä½æãã¦Import var holderInstance = Activator.CreateInstance(holderType); this.service.SatisfyImportsOnce(holderInstance, b); // Valuesããããã£ã®å¤ãåå¾ãã¦è¿å´ var valuePropertyInfo = holderType.GetTypeInfo().GetDeclaredProperty("Values"); return (IEnumerable<object>) valuePropertyInfo.GetValue(holderInstance); } private object DoGetInstance(Type serviceType, string key) { // SingleValueHolder<T>åãä½æ var holderType = typeof(SingleValueHolder<>).MakeGenericType(serviceType); // Valueããããã£ã«Importå±æ§ãã¤ãã¦ãã¤ã¡ã¼ã¸ // ã³ã³ãã©ã¯ãåãæå®ããã¦ããå ´åã¯ããã追å ãã var b = new RegistrationBuilder(); b.ForType(holderType) .ImportProperties(p => true, (p, c) => { if (!string.IsNullOrEmpty(key)) { c.AsContractName(key); } }); // SingleValueHolder<T>åã®ã¤ã³ã¹ã¿ã³ã¹ãä½æãã¦Import var holderInstance = Activator.CreateInstance(holderType); this.service.SatisfyImportsOnce(holderInstance, b); // Valueããããã£ã®å¤ãåå¾ãã¦è¿å´ var valuePropertyInfo = holderType.GetTypeInfo().GetDeclaredProperty("Value"); return valuePropertyInfo.GetValue(holderInstance); } public IEnumerable<TService> GetAllInstances<TService>() { return DoGetAllInstances(typeof(TService)).Cast<TService>(); } public IEnumerable<object> GetAllInstances(Type serviceType) { return DoGetAllInstances(serviceType); } public TService GetInstance<TService>(string key) { return (TService)DoGetInstance(typeof(TService), key); } public TService GetInstance<TService>() { return (TService) DoGetInstance(typeof(TService), null); } public object GetInstance(Type serviceType, string key) { return DoGetInstance(serviceType, key); } public object GetInstance(Type serviceType) { return DoGetInstance(serviceType, null); } } /// <summary> /// åä¸ã®ã¤ã³ã¹ã¿ã³ã¹ãImportããããã®ã¯ã©ã¹ /// </summary> /// <typeparam name="T"></typeparam> class SingleValueHolder<T> { public T Value { get; set; } } /// <summary> /// è¤æ°ã®ã¤ã³ã¹ã¿ã³ã¹ãImportããããã®ã¯ã©ã¹ /// </summary> /// <typeparam name="T"></typeparam> class ManyValueHolder<T> { public IEnumerable<T> Values { get; set; } } }
ãããªæãã§å®è£ å®äºï¼éãããã¹ãã¯ä»¥ä¸ã®ãããªæãã
namespace MefServiceLocatorImpl.Test { using System.ComponentModel.Composition; using System.ComponentModel.Composition.Hosting; using System.Linq; using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting; using SampleImplementation; [TestClass] public class MefServiceLocatorTest { private MefServiceLocator locator; [TestInitialize] public void Initialize() { this.locator = new MefServiceLocator( new AssemblyCatalog(typeof(MefServiceLocatorTest).GetTypeInfo().Assembly)); } [TestCleanup] public void Cleanup() { this.locator = null; } [TestMethod] public void InitTest() { Assert.IsNotNull(this.locator); } [TestMethod] public void SingleExportTest() { var target = locator.GetInstance<ExportTarget>(); Assert.IsNotNull(target); } [TestMethod] public void NamedSingleExportTest() { var target = locator.GetInstance<NamedExportTarget>("Sample"); Assert.IsNotNull(target); } [TestMethod] [ExpectedException(typeof(CompositionException))] public void NamedSingleExportMissingTest() { locator.GetInstance<NamedExportTarget>("MissingName"); } [TestMethod] public void ManyExportTest() { var targets = locator.GetAllInstances<IManyExportTarget>(); Assert.IsNotNull(targets); Assert.AreEqual(targets.Count(), 3); } } [Export] public class ExportTarget { } [Export("Sample")] public class NamedExportTarget { } public interface IManyExportTarget { } [Export(typeof(IManyExportTarget))] public class ManyExportTarget1 : IManyExportTarget { } [Export(typeof(IManyExportTarget))] public class ManyExportTarget2 : IManyExportTarget { } [Export(typeof(IManyExportTarget))] public class ManyExportTarget3 : IManyExportTarget { } }
ããã§ãªã¼ã«ã°ãªã¼ã³ï¼ã¨ãããã¨ã§MVVM Light 4ã®SimpleIoCãããªãã¦MEFã使ããããã«ãªãããã§ãã