我有一个对象,它接受一个有序的List(IOrderedEnumerable)项,其中项的顺序很重要。
public class OrderedListWorker : IListWorker
{
private OrderedListWorker(IOrderedEnumerable<IListItem> orderedListItems)
{
foreach (var listItem in orderedListItems)
listItem.DoSomethingWhereOrderMatters();
}
}
我有多个IListItem
类型的对象。
如何向Autofac注册OrderedListWorker
并确保在运行时以特定顺序获取ListItem?
我发现This Post无法保证订单,但我不确定如何保证订单。
答案 0 :(得分:4)
我有一个解决方案,即我在上面链接的帖子中IOrderedEnumerable
和ResolveOrdered<TComponent>
解决方案的组合。
使用AutofacExtensions类:
public static class AutofacExtensions
{
private const string OrderString = "WithOrderTag";
private static int _orderCounter;
public static IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle>
WithOrder<TLimit, TActivatorData, TRegistrationStyle>(
this IRegistrationBuilder<TLimit, TActivatorData, TRegistrationStyle> registrationBuilder)
{
return registrationBuilder.WithMetadata(OrderString, Interlocked.Increment(ref _orderCounter));
}
public static IOrderedEnumerable<TComponent> ResolveOrdered<TComponent>(this IComponentContext context)
{
return
context.Resolve<IEnumerable<Meta<TComponent>>>()
.OrderBy(m => m.Metadata[OrderString])
.Select(m => m.Value).OrderBy(c => true);
}
}
我可以按如下方式指定我的注册:
builder.RegisterType<ListItemA>().As<IListItem>().WithOrder();
builder.RegisterType<ListItemB>().As<IListItem>().WithOrder();
builder.RegisterType<OrderedListWorker>()
.As<IListWorker>()
.WithParameter(
new ResolvedParameter(
(info, context) => true,
(info, context) => context.ResolveOrdered<IListItem>()));
答案 1 :(得分:0)
我知道这是一个老问题,但今天我遇到了类似的问题,我想我会分享我的解决方案。
注册:
protected override void Load(ContainerBuilder builder)
{
builder.RegisterOrdered<IListItem>(scope =>
{
scope.Register<Item1>();
scope.Register<Item2>();
});
}
基础设施:
public static class AutofacExtensions
{
public static void RegisterOrdered<TService>(this ContainerBuilder builder, Action<IOrderedScope> setter)
{
var scope = new OrderedScope<TService>(builder);
setter(scope);
builder.Register(ctx => ctx.Resolve<IEnumerable<TService>>().OrderBy(x => scope.OrderedTypes[x.GetType()]));
}
private class OrderedScope<TService> : IOrderedScope
{
private readonly ContainerBuilder _builder;
private int _order = 1;
public OrderedScope(ContainerBuilder builder)
{
_builder = builder;
OrderedTypes = new Dictionary<Type, int>();
}
public Dictionary<Type, int> OrderedTypes {get;}
public IRegistrationBuilder<T, ConcreteReflectionActivatorData, SingleRegistrationStyle> Register<T>()
{
OrderedTypes.Add(typeof(T), _order++);
return _builder.RegisterType<T>().As<TService>();
}
}
}
public interface IOrderedScope
{
IRegistrationBuilder<T, ConcreteReflectionActivatorData, SingleRegistrationStyle> Register<T>();
}
用法:
public class OrderedListWorker : IListWorker
{
public OrderedListWorker(IOrderedEnumerable<IListItem> items)
{
}
}