Внедрение зависимости для Windows Phone 7

Я пытался использовать Единицу 2,0 беты 2 для Silverlight в моем проекте Windows Phone 7, и я продолжал получать этот катастрофический отказ:

Microsoft. Методы. Единица. Silverlight.dll! Microsoft. Методы. 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 

Думая я мог разрешить его, я попробовал несколько вещей, но напрасно.

Оказывается, что это - довольно фундаментальная проблема и мое предположение, что Windows Phone 7 является Silverlight 3 +, Некоторый другой материал является неправильным. Эта страница описывает различия между Мобильной Silverlight и Silverlight 3.

Особенно интересный это:

Система. Отражение. Испустите пространство имен, не поддерживается в Silverlight для Windows Phone.

Это точно, почему Единица отказывает по телефону, DynamicMethodConstructorStrategy использование класса System.Reflection.Emit вполне экстенсивно...

Таким образом, вопрос, что альтернатива Единице там для Windows Phone 7?

11
задан Igor Zevaka 3 May 2010 в 04:44
поделиться

3 ответа

Если вы не можете найти контейнер IOC, который работает на Windows Phone 7 (и я не удивлюсь, что вы не можете этого сделать), я бы предложил использовать другой DI. стратегия .

2
ответ дан 3 December 2019 в 06:45
поделиться

Итак, в духе ответов на мои собственные вопросы, я собрал простой контейнер 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
7
ответ дан 3 December 2019 в 06:45
поделиться

Я только начал собирать проект средств расширения Windows Phone 7 на codeplex. Текущая зарегистрированная версия поддерживает IoC с неявным DI вместе с Common Service Locator, чтобы обеспечить полную абстракцию вашего кода и контейнера, который они используют.

Проверьте это здесь: http://wp7.codeplex.com

Ура, Саймон Харт

2
ответ дан 3 December 2019 в 06:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: