I'm re开发者_如何学运维gistering components with the following code:
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();
}
}
Then I have a class which implements two interfaces:
class StandardConsole : IStartable, IConsumer<ConsoleCommand>
If I resolve IStartable
I get one instance, if I resolve IConsumer<ConsoleCommand>
I get another.
How do I get the same instance for both interfaces?
builder.RegisterType<StandardConsole>()
.As<IStartable>()
.As<IConsumer<ConsoleCommand>>()
.SingleInstance();
Very widely used feature of Autofac- any problems then there is a bug somewhere :)
Hth Nick
Edit By the looks of it, you're after the overload of As() that takes an IEnumerable<Type>() - check out all of the As() overloads using IntelliSense, something there should fit your scenario. As another commenter noted, you need to update the question with all of the info.
Updated with suggestion from Nicholas:
Here is how it's done in 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;
}
I know this is an old thread, but here is the solution for Ninject.
kernel.Bind<StandardConsole>().ToSelf().InSingletonScope();
kernel.Bind<IStartable>().ToMethod(ctx => ctx.Kernel.Get<StandardConsole>());
kernel.Bind<IConsumer<ConsoleCommand>>().ToMethod(ctx => ctx.Kernel.Get<StandardConsole>());
I'm not familiar with Autofac, but you ought to be able to Register for one type a lambda expression that returns the Resolve of the other type.
something like:
builder.Register<IStartable>().As<StandardConsole>().Singleton();
builder.Register<IConsumer<ConsoleCommand>>().As( x => builder.Resolve<IStartable>() );
This is me taking a wild stab in the dark as I don't know Autofac.
If you add:
build.RegisterType<StandardConsole>.As(StandardConsole).SingleInstance()
then shouldn't it resolve IStartable to StandardConsole then StandardConsole to the singleton instance of StandardConsole? Ditto with IConsumer.
EDIT: From logging at your blog, couldn't you change the following:
assemblies.Each(assembly => assembly.FindComponents((i, c) => builder.RegisterType(c).As(i).SingleInstance()));
to
assemblies.Each(assembly => assembly.FindComponents((i, c) => {
builder.RegisterType(c).As(i).SingleInstance();
builder.RegisterType(c).As(c).SingleInstance();
}));
精彩评论