代码之家  ›  专栏  ›  技术社区  ›  Igor Zevaka

Windows Phone 7的依赖注入

  •  11
  • Igor Zevaka  · 技术社区  · 14 年前

    我试图在我的Windows Phone 7项目中使用Unity 2.0 beta 2 for Silverlight,但一直遇到以下问题:

    Microsoft.Practices.Unity.Silverlight.dll!Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.DynamicMethodConstructorStrategy()+0x1f字节

    Microsoft.Practices.Unity.Silverlight.dll!Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.DynamicMethodConstructorStrategy() + 0x1f bytes   mscorlib.dll!System.Reflection.RuntimeConstructorInfo.InternalInvoke(System.Reflection.RuntimeConstructorInfo rtci = {System.Reflection.RuntimeConstructorInfo}, System.Reflection.BindingFlags invokeAttr = Default, System.Reflection.Binder binder = null, object parameters = {object[0]}, System.Globalization.CultureInfo culture = null, bool isBinderDefault = false, System.Reflection.Assembly caller = null, bool verifyAccess = true, ref System.Threading.StackCrawlMark stackMark = LookForMyCaller)  
    mscorlib.dll!System.Reflection.RuntimeConstructorInfo.InternalInvoke(object obj = null, System.Reflection.BindingFlags invokeAttr = Default, System.Reflection.Binder binder = null, object[] parameters = {object[0]}, System.Globalization.CultureInfo culture = null, ref System.Threading.StackCrawlMark stackMark = LookForMyCaller) + 0x103 bytes 
    mscorlib.dll!System.Activator.InternalCreateInstance(System.Type type = {Name = "DynamicMethodConstructorStrategy" FullName = "Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy"}, bool nonPublic = false, ref System.Threading.StackCrawlMark stackMark = LookForMyCaller) + 0xf0 bytes mscorlib.dll!System.Activator.CreateInstance() + 0xc bytes 
    Microsoft.Practices.Unity.Silverlight.dll!Microsoft.Practices.ObjectBuilder2.StagedStrategyChain.AddNew(Microsoft.Practices.Unity.ObjectBuilder.UnityBuildStage stage = Creation) + 0x1d bytes    
    Microsoft.Practices.Unity.Silverlight.dll!Microsoft.Practices.Unity.UnityDefaultStrategiesExtension.Initialize() + 0x6c bytes   
    Microsoft.Practices.Unity.Silverlight.dll!Microsoft.Practices.Unity.UnityContainerExtension.InitializeExtension(Microsoft.Practices.Unity.ExtensionContext context = {Microsoft.Practices.Unity.UnityContainer.ExtensionContextImpl}) + 0x31 bytes  
    Microsoft.Practices.Unity.Silverlight.dll!Microsoft.Practices.Unity.UnityContainer.AddExtension(Microsoft.Practices.Unity.UnityContainerExtension extension = {Microsoft.Practices.Unity.UnityDefaultStrategiesExtension}) + 0x1a bytes 
    Microsoft.Practices.Unity.Silverlight.dll!Microsoft.Practices.Unity.UnityContainer.UnityContainer() + 0xf bytes 
    

    我想我能解决这个问题,我试过几次,但都没有用。

    事实证明,这是一个相当基本的问题,我的假设WindowsPhone7是Silverlight3+其他一些东西是错误的。这个 page

    特别令人感兴趣的是:

    Silverlight for Windows Phone不支持System.Reflection.Emit命名空间。

    这就是为什么统一在电话里崩溃, DynamicMethodConstructorStrategy System.Reflection.Emit 相当广泛。。。

    所以问题是,

    6 回复  |  直到 14 年前
        1
  •  5
  •   Alex Angas Colin    14 年前

    Funq 已经开发了一年多,现在已经有了1.0版本。它的设计速度很快,在紧凑的框架和WindowsPhone7下运行 screencast series

    另外,我能找到的最新性能测试是 from March 2009

        2
  •  7
  •   Igor Zevaka    14 年前

    因此,为了回答我自己的问题,我将一个简单的DI容器(使用 Activator.CreateInstance

    似乎在做这项工作。以后会担心性能。

    public class DuplicateRegistrationException : Exception {
        public DuplicateRegistrationException() { }
        public DuplicateRegistrationException(string message) : base(message) { }
        public DuplicateRegistrationException(string message, Exception inner) : base(message, inner) { }
    }
    
    public interface IDIContainer {
        void Register<TIntf, TClass> () where TIntf: class where TClass : TIntf;
        TIntf Resolve<TIntf>() where TIntf : class;
        void RegisterInstance<TIntf>(TIntf instance);
    }
    
    public class DIContainer :  IDIContainer{
    
        Dictionary<Type, Type> m_TypeRegistrations;
        Dictionary<Type, object> m_InstanceRegistrations;
    
        public DIContainer() {
            m_TypeRegistrations = new Dictionary<Type, Type>();
            m_InstanceRegistrations = new Dictionary<Type, object>();
        }
    
        #region IDIContainer Members
    
        public void Register<TIntf, TClass>()
            where TIntf : class
            where TClass : TIntf {
                if(DoesRegistrationExist<TIntf>())
                    throw new DuplicateRegistrationException("Can only contain one registration per type");
                m_TypeRegistrations.Add(typeof(TIntf), typeof(TClass));
        }
    
        public TIntf Resolve<TIntf>() where TIntf : class {
            return Resolve(typeof(TIntf)) as TIntf;
        }
    
        private object Resolve(Type type) {
            if(!m_TypeRegistrations.ContainsKey(type)) {
                if(!m_InstanceRegistrations.ContainsKey(type))
                    throw new NotSupportedException("Cannot find registration for type " + type.FullName + ".");
                else
                    return m_InstanceRegistrations[type];
            } else {
                var createdType = m_TypeRegistrations[type];
    
                ConstructorInfo[] constructors = createdType.GetConstructors();
                ConstructorInfo mostSpecificConstructor = null;
                foreach(var c in constructors) {
                    if(mostSpecificConstructor == null || mostSpecificConstructor.GetParameters().Length < c.GetParameters().Length) {
                        mostSpecificConstructor = c;
                    }
                }
    
                List<object> constructorParameters = new List<object>();
                foreach(var a in mostSpecificConstructor.GetParameters()) {
                    constructorParameters.Add(Resolve(a.ParameterType));
                }
    
                return Activator.CreateInstance(createdType, constructorParameters.ToArray());
            }
        }
    
        private bool DoesRegistrationExist<T>() {
            return m_InstanceRegistrations.ContainsKey(typeof(T)) || m_TypeRegistrations.ContainsKey(typeof(T));
        }
    
        public void RegisterInstance<TIntf>(TIntf instance) {
            if(DoesRegistrationExist<TIntf>()) {
                throw new DuplicateRegistrationException("Can only contain one registration per type");
            }
            m_InstanceRegistrations.Add(typeof(TIntf), instance);
        }
    
    
        #endregion
    
        3
  •  2
  •   Brent Arias    14 年前

    如果你找不到一个可以在WindowsPhone7上运行的IOC容器(你找不到我也不会感到惊讶),那么我建议你使用它 a different DI strategy .

        4
  •  2
  •   Simon Hart    14 年前

    我刚刚开始在codeplex上创建一个windowsphone7扩展工具项目。签入的当前版本支持带有隐式DI的IoC以及公共服务定位器,以允许对代码及其使用的容器进行完全抽象。

    请访问: http://wp7.codeplex.com

    干杯, 西蒙哈特

        5
  •  1
  •   ctacke    14 年前

    OpenNETCF.IoC framework

    它是以SCSF/CAB(在对象模型中,不是蹩脚的perf)为模型的,因此许多教程都是有效的,您可以利用现有的知识和代码资产。

        6
  •  1
  •   Ilya Builuk    13 年前

    “世界不需要另一个容器”

    • 对象组成
    • 生命周期管理
    • 它允许您使用面向方面的编程方法

    容器是PhoneCore框架的一部分,您可以在这里找到: http://phonecore.codeplex.com