Я регистрирую компоненты в следующем коде:
StandardKernel kernel = new StandardKernel();
string currentDirectory = Path.GetDirectoryName(GetType().Assembly.Location)
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (!Path.GetDirectoryName(assembly.Location).Equals(currentDirectory))
continue;
foreach (var type in assembly.GetTypes())
{
if (!type.IsComponent())
continue;
foreach (var @interface in type.GetInterfaces())
kernel.Bind(@interface).To(type).InSingletonScope();
}
}
Затем у меня есть класс, который реализует два интерфейса:
class StandardConsole : IStartable, IConsumer<ConsoleCommand>
Если я решаю IStartable
Я получаю один экземпляр, если я решаю IConsumer<ConsoleCommand>
Я получаю другого.
Как я получаю тот же экземпляр для обоих интерфейсов?
builder.RegisterType<StandardConsole>()
.As<IStartable>()
.As<IConsumer<ConsoleCommand>>()
.SingleInstance();
Очень широко используемая функция Autofac - если возникают проблемы, значит, где-то есть ошибка :)
Hth Nick
Edit Судя по всему, вам нужна перегрузка As(), которая принимает IEnumerable
Это я принимаю дикий удар в темноте, так как я не знаю Autofac.
Если вы добавите:
build.RegisterType<StandardConsole>.As(StandardConsole).SingleInstance()
, тогда не следует ли разрешать IStartable в StandardConsole, а затем StandardConsole в одноэлементный экземпляр StandardConsole? То же самое с IConsumer.
РЕДАКТИРОВАТЬ: Не могли бы вы изменить следующее:
assemblies.Each(assembly => assembly.FindComponents((i, c) => builder.RegisterType(c).As(i).SingleInstance()));
на
assemblies.Each(assembly => assembly.FindComponents((i, c) => {
builder.RegisterType(c).As(i).SingleInstance();
builder.RegisterType(c).As(c).SingleInstance();
}));
Я не знаком с Autofac, но вы должны уметь Чтобы зарегистрировать для одного типа лямбда-выражение, которое возвращает Resolve другого типа.
что-то вроде:
builder.Register<IStartable>().As<StandardConsole>().Singleton();
builder.Register<IConsumer<ConsoleCommand>>().As( x => builder.Resolve<IStartable>() );
Обновлено с предложением Николаса:
Вот как это сделано в autofac
private void BuildComponents(ContainerBuilder builder)
{
string currentDirectory = Path.GetDirectoryName(GetType().Assembly.Location);
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
if (!Path.GetDirectoryName(assembly.Location).Equals(currentDirectory))
continue;
builder.RegisterAssemblyTypes(assembly)
.Where(t => t.IsComponent())
.AsImplementedInterfaces()
.SingleInstance();
}
}
public static bool IsComponent(this Type value)
{
return value.GetType().GetCustomAttributes(typeof (ComponentAttribute), true).Length > 0;
}