Платформа единицы DependencyAttribute только работает на общественные собственности?

вы можете использовать row_number() максимальную поддержку дБмс

select * from 
(
select *, row_number() over(partition by bikename order by NumOfUsages desc) rn
from table_name
)t where t.rn=1
9
задан CodingWithSpike 23 January 2009 в 16:49
поделиться

6 ответов

Много позже lof ввода по абсолютному адресу вокруг в отражателе, я понял это. По умолчанию, код, который находит конструктора для вызовов инжекции конструктора:

ConstructorInfo[] constructors = typeToConstruct.GetConstructors()

Без BindingFlags, который только обнаружит общедоступных конструкторов. С некоторым обманом (как в скопировать/вставить от отражателя) можно сделать UnityContainerExtension, который действительно все равно наполняет как реализация по умолчанию, но изменяет вызов на GetConstructors () к:

ConstructorInfo[] constructors = typeToConstruct..GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)

Затем добавьте расширение в контейнер единицы. Реализованный extenstion является ~100 строками кода, таким образом, я не вставлял его здесь. Если кто-либо хочет это, сообщить мне...

Новый случай эксплуатационного испытания. Обратите внимание, что созданные классы всей Единицы являются теперь внутренними:

[TestFixture]
public class UnityFixture
{
    [Test]
    public void UnityCanSetInternalDependency()
    {
        UnityContainer container = new UnityContainer();
        container.AddNewExtension<InternalConstructorInjectionExtension>();
        container.RegisterType<HasInternalDep, HasInternalDep>();
        container.RegisterType<TheDep, TheDep>();

        var i = container.Resolve<HasInternalDep>();
        Assert.IsNotNull(i);
        Assert.IsNotNull(i.dep);
    }
}


internal class HasInternalDep
{
    internal HasInternalDep(TheDep dep)
    {
        this.dep = dep;
    }

    internal TheDep dep { get; set; }
}

internal class TheDep
{
}

Я уверен, что могу сделать расширение, чтобы сделать то же для разрешения непубличных свойств, но тот код был намного более сложным :)

2
ответ дан 4 December 2019 в 09:38
поделиться

Другое решение состоит в том, чтобы использовать [InjectionMethod] на методе, куда Вы передаете зависимость в класс.

public class MyClass {
private ILogger logger;

[InjectionMethod]
public void Init([Dependency] ILogger logger)
{
    this.logger = logger;

... и т.д.


и вызов его:

container.BuildUp<MyClass>(instanceOfMyClass);

который назовет Init с зависимостью от единицы.

не вполне решил проблему, я знаю..., но

:-) J

6
ответ дан 4 December 2019 в 09:38
поделиться

Если свойство является только добиранием, имеет больше смысла использовать инжекцию конструктора, а не инжекцию свойства.

Если бы Единица действительно использовала отражение для установки частных или внутренних участников, то это было бы подвергнуто ограничениям безопасности доступа к коду. А именно, это не работало бы в среде низкого доверия.

5
ответ дан 4 December 2019 в 09:38
поделиться

На основе ответа Kent B я изменился на инжекцию конструктора использования, которая действительно работает на общедоступные классы. Однако основная проблема все еще существует, где что-либо Вы когда-либо хотите присвоиться или присвоились Единицей, должно быть общедоступным. Это включает сами классы.

Новый модульный тест:

    [TestFixture]
public class UnityFixture
{
    [Test]
    public void UnityCanSetInternalDependency()
    {
        UnityContainer container = new UnityContainer();
        container.RegisterType<HasInternalDep, HasInternalDep>();
        container.RegisterType<TheDep, TheDep>();

        var i = container.Resolve<HasInternalDep>();
        Assert.IsNotNull(i);
        Assert.IsNotNull(i.dep);
    }
    }

internal class HasInternalDep
{
    internal HasInternalDep(TheDep dep)
    {
        this._Dep = dep;
    }

    private TheDep _Dep;
        internal TheDep dep
        {
            get { return _Dep; }
        }
}

internal class TheDep
{
}
}

С атрибутами сборки:

[assembly: InternalsVisibleTo("Microsoft.Practices.Unity")]
[assembly: InternalsVisibleTo("Microsoft.Practices.Unity.Configuration")]
[assembly: InternalsVisibleTo("Microsoft.Practices.ObjectBuilder2")]

Сбои с ошибкой:

The type HasInternalDep does not have an accessible constructor.
at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, String name)

Настолько в целом кажется, что, если Вы хотите использовать Единицу, в основном просто необходимо покрыть, отмечают все общедоступное. Действительно ужасный для утилиты/библиотеки .dll...

0
ответ дан 4 December 2019 в 09:38
поделиться

Это мой класс расширения внутреннего конструктора-инжектора:

Большая потенциальная проблема: 99% из них - это копия / вставка кода Unity из рефлектора .NET из версии Unity 4.1.0.0. Более новые версии Unity могут изменить реализацию и сломать это расширение или вызвать нестабильные ошибки. Вы предупреждены!

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.ObjectBuilder;
using Microsoft.Practices.Unity.Utility;

namespace MyApp.Unity.Configuration
{
    /// <summary>
    /// This extension changes the behavior of Unity constructor injection to allow the use of non-public constructors.
    /// By default, Unity/ObjectBuilder would call Type.GetConstructors() to get the constructors. With the default binding
    /// flags, this only returns public constructors.
    /// The code here is 99% copy/paste from Reflector's dissassembly of the default Unity/OB implementation.
    /// My only change was to add binding flags to get all constructors, not just public ones.
    /// For more info, see: Microsoft.Practices.Unity.ObjectBuilder.DefaultUnityConstructorSelectorPolicy
    /// </summary>
    public class InternalConstructorSelectorPolicy : IConstructorSelectorPolicy
    {
        protected IDependencyResolverPolicy CreateResolver(ParameterInfo param)
        {
            List<DependencyResolutionAttribute> list = new List<DependencyResolutionAttribute>(Sequence.OfType<DependencyResolutionAttribute>(param.GetCustomAttributes(false)));
            if (list.Count > 0)
            {
                return list[0].CreateResolver(param.ParameterType);
            }
            return new NamedTypeDependencyResolverPolicy(param.ParameterType, null);
        }

        private SelectedConstructor CreateSelectedConstructor(IBuilderContext context, ConstructorInfo ctor)
        {
            SelectedConstructor constructor = new SelectedConstructor(ctor);
            foreach (ParameterInfo info in ctor.GetParameters())
            {
                string buildKey = Guid.NewGuid().ToString();
                IDependencyResolverPolicy policy = this.CreateResolver(info);
                context.PersistentPolicies.Set<IDependencyResolverPolicy>(policy, buildKey);
                DependencyResolverTrackerPolicy.TrackKey(context.PersistentPolicies, context.BuildKey, buildKey);
                constructor.AddParameterKey(buildKey);
            }
            return constructor;
        }

        private ConstructorInfo FindInjectionConstructor(Type typeToConstruct)
        {
            ConstructorInfo[] infoArray = Array.FindAll<ConstructorInfo>(typeToConstruct.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic), delegate(ConstructorInfo ctor)
            {
                return ctor.IsDefined(typeof(InjectionConstructorAttribute), true);
            });
            switch (infoArray.Length)
            {
                case 0:
                    return null;

                case 1:
                    return infoArray[0];
            }
            throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Resources.MultipleInjectionConstructors", new object[] { typeToConstruct.Name }));
        }

        private ConstructorInfo FindLongestConstructor(Type typeToConstruct)
        {
            ConstructorInfo[] constructors = typeToConstruct.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            Array.Sort<ConstructorInfo>(constructors, new ConstructorLengthComparer());
            switch (constructors.Length)
            {
                case 0:
                    return null;

                case 1:
                    return constructors[0];
            }
            int length = constructors[0].GetParameters().Length;
            if (constructors[1].GetParameters().Length == length)
            {
                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Resources.AmbiguousInjectionConstructor", new object[] { typeToConstruct.Name, length }));
            }
            return constructors[0];
        }

        public virtual SelectedConstructor SelectConstructor(IBuilderContext context)
        {
            Type typeToConstruct = BuildKey.GetType(context.BuildKey);
            ConstructorInfo ctor = this.FindInjectionConstructor(typeToConstruct) ?? this.FindLongestConstructor(typeToConstruct);
            if (ctor != null)
            {
                return this.CreateSelectedConstructor(context, ctor);
            }
            return null;
        }

        // Nested Types
        private class ConstructorLengthComparer : IComparer<ConstructorInfo>
        {
            // Methods
            public int Compare(ConstructorInfo x, ConstructorInfo y)
            {
                return (y.GetParameters().Length - x.GetParameters().Length);
            }
        }
    }

    /// <summary>
    /// Registeres the InternalConstructorSelectorPolicy with the Unity container.
    /// </summary>
    public class InternalConstructorInjectionExtension : UnityContainerExtension
    {
        protected override void Initialize()
        {
            this.Context.Policies.SetDefault(typeof(IConstructorSelectorPolicy), new InternalConstructorSelectorPolicy());
        }
    }
}
0
ответ дан 4 December 2019 в 09:38
поделиться

ОБНОВЛЕНИЕ Enterprise Library 5.0

Как предупреждал rally52rs, обновление до EntLib5.0 нарушает его реализацию. Используя тот же подход, что и Ралли, я подумал о новой кодовой базе и разработал следующую совместимую с 5.0 версию InternalConstructorSelectorPolicy.

Обратите внимание, что моя версия специально ограничивает себя внутренними конструкторами в методе FindLongestConstructor. В этом отношении мой код функционально отличается от кода Ралли .

public class InternalConstructorSelectorPolicy : IConstructorSelectorPolicy, IBuilderPolicy 
{
    private IDependencyResolverPolicy CreateResolver(ParameterInfo parameter)
    {
        List<DependencyResolutionAttribute> attrs = parameter.GetCustomAttributes(false).OfType<DependencyResolutionAttribute>().ToList<DependencyResolutionAttribute>();
        if (attrs.Count > 0)
        {
            return attrs[0].CreateResolver(parameter.ParameterType);
        }
        return new NamedTypeDependencyResolverPolicy(parameter.ParameterType, null);
    }

    private SelectedConstructor CreateSelectedConstructor(IBuilderContext context, IPolicyList resolverPolicyDestination, ConstructorInfo ctor)
    {
        SelectedConstructor result = new SelectedConstructor(ctor);
        foreach (ParameterInfo param in ctor.GetParameters())
        {
            string key = Guid.NewGuid().ToString();
            IDependencyResolverPolicy policy = this.CreateResolver(param);
            resolverPolicyDestination.Set<IDependencyResolverPolicy>(policy, key);
            DependencyResolverTrackerPolicy.TrackKey(resolverPolicyDestination, context.BuildKey, key);
            result.AddParameterKey(key);
        }
        return result;
    }

    private static ConstructorInfo FindInjectionConstructor(Type typeToConstruct)
    {
        ConstructorInfo[] injectionConstructors = typeToConstruct
            .GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
            .Where<ConstructorInfo>(delegate(ConstructorInfo ctor)
        {
            return ctor.IsDefined(typeof(InjectionConstructorAttribute), true);
        }).ToArray<ConstructorInfo>();
        switch (injectionConstructors.Length)
        {
            case 0:
                return null;

            case 1:
                return injectionConstructors[0];
        }
        throw new InvalidOperationException(string.Format("Multiple constructors found for {0}" , typeToConstruct.Name ));
    }

    private static ConstructorInfo FindLongestConstructor(Type typeToConstruct)
    {
        var constructors =
            Array.FindAll(
                typeToConstruct.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic),
                ctor => !ctor.IsFamily && !ctor.IsPrivate);  //Filter out protected and private constructors

        Array.Sort<ConstructorInfo>(constructors, new ConstructorLengthComparer());
        switch (constructors.Length)
        {
            case 0:
                return null;

            case 1:
                return constructors[0];
        }
        int paramLength = constructors[0].GetParameters().Length;
        if (constructors[1].GetParameters().Length == paramLength)
        {
            throw new InvalidOperationException(string.Format("Ambiguous constructor found for {0}", typeToConstruct.Name));
        }
        return constructors[0];
    }

    public SelectedConstructor SelectConstructor(IBuilderContext context, IPolicyList resolverPolicyDestination)
    {
        Type typeToConstruct = context.BuildKey.Type;
        ConstructorInfo ctor = FindInjectionConstructor(typeToConstruct) ?? FindLongestConstructor(typeToConstruct);
        if (ctor != null)
        {
            return this.CreateSelectedConstructor(context, resolverPolicyDestination, ctor);
        }
        return null;
    }

    // Nested Types
    private class ConstructorLengthComparer : IComparer<ConstructorInfo>
    {
        // Methods
        public int Compare(ConstructorInfo x, ConstructorInfo y)
        {
            return (y.GetParameters().Length - x.GetParameters().Length);
        }
    }
}
3
ответ дан 4 December 2019 в 09:38
поделиться
Другие вопросы по тегам:

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