вы можете использовать row_number()
максимальную поддержку дБмс
select * from
(
select *, row_number() over(partition by bikename order by NumOfUsages desc) rn
from table_name
)t where t.rn=1
Много позже 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
{
}
Я уверен, что могу сделать расширение, чтобы сделать то же для разрешения непубличных свойств, но тот код был намного более сложным :)
Другое решение состоит в том, чтобы использовать [InjectionMethod] на методе, куда Вы передаете зависимость в класс.
public class MyClass {
private ILogger logger;
[InjectionMethod]
public void Init([Dependency] ILogger logger)
{
this.logger = logger;
... и т.д.
и вызов его:
container.BuildUp<MyClass>(instanceOfMyClass);
который назовет Init с зависимостью от единицы.
не вполне решил проблему, я знаю..., но
:-) J
Если свойство является только добиранием, имеет больше смысла использовать инжекцию конструктора, а не инжекцию свойства.
Если бы Единица действительно использовала отражение для установки частных или внутренних участников, то это было бы подвергнуто ограничениям безопасности доступа к коду. А именно, это не работало бы в среде низкого доверия.
На основе ответа 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...
Это мой класс расширения внутреннего конструктора-инжектора:
Большая потенциальная проблема: 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());
}
}
}
ОБНОВЛЕНИЕ 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);
}
}
}