C# 为多个接口返回同一实例
我正在使用以下代码注册组件:C# 为多个接口返回同一实例,c#,singleton,autofac,C#,Singleton,Autofac,我正在使用以下代码注册组件: StandardKernel kernel = new StandardKernel(); string currentDirectory = Path.GetDirectoryName(GetType().Assembly.Location) foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (!Path.GetDirectoryName(assembly.Loc
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>
class StandardConsole:IStartable,IConsumer
如果我解析IStartable
我会得到一个实例,如果我解析IConsumer
我会得到另一个实例
如何为两个接口获得相同的实例?这是我在暗中摸索,因为我不知道Autofac 如果您添加:
build.RegisterType<StandardConsole>.As(StandardConsole).SingleInstance()
到
我不熟悉Autofac,但您应该能够为一种类型注册一个lambda表达式,该表达式返回另一种类型的解析 比如:
builder.Register<IStartable>().As<StandardConsole>().Singleton();
builder.Register<IConsumer<ConsoleCommand>>().As( x => builder.Resolve<IStartable>() );
builder.Register().As().Singleton();
builder.Register().As(x=>builder.Resolve());
builder.RegisterType()
.As()
.As()
.SingleInstance();
Autofac使用非常广泛的功能-如果出现任何问题,则在某个地方会出现错误:)
嗯
尼克
编辑从外观上看,您正在寻找需要IEnumerable()的As()重载-使用IntelliSense检查所有As()重载,那里应该适合您的场景。另一位评论者指出,你需要用所有信息更新问题。根据尼古拉斯的建议更新: 下面是如何在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;
}
我知道这是一个旧线程,但这里是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>());
kernel.Bind().ToSelf().InSingletonScope();
kernel.Bind().ToMethod(ctx=>ctx.kernel.Get());
kernel.Bind().ToMethod(ctx=>ctx.kernel.Get());
不行。我在使用ComponentAttribute的类之后扫描应用程序目录中的所有程序集,并用它们实现的所有接口注册它们。那就很难按照你的建议去做了。请参阅我对dave thiebenNo的评论,我不想使用IEnumerable注册。这是autofac的内置功能。另外,我不能使用泛型参数,因为我使用反射来注册所有组件。我知道你的意思(我写的;)-我建议的功能是不同的。如果您有一个要公开的接口列表(i1、i2、i3..),您可以将整个列表传递给一个As()调用。您还可以查看RegisterAssemblyTypes(myAsm).AsImplementedInterfaces(),它可以扩展到您的文章所建议的内容-如果您愿意,欢迎您通过Autofac讨论论坛来完成此工作。抱歉=)只是厌倦了没有使用Autofac的人的回答。我已经用扫描文章中的代码更新了下面的答案。谢谢这个问题应该分为两个部分,一个是Ninject,另一个是autofac。@JeffWalkerCodeRanger:你给了-1分吗?:)Ninject侧有3或4个DUP,请参见在此基础上删除的Ninject标记。建议从问题中删除ninject方面,因为这会导致无法回答的问题question@Jeff:见
builder.RegisterType<StandardConsole>()
.As<IStartable>()
.As<IConsumer<ConsoleCommand>>()
.SingleInstance();
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;
}
kernel.Bind<StandardConsole>().ToSelf().InSingletonScope();
kernel.Bind<IStartable>().ToMethod(ctx => ctx.Kernel.Get<StandardConsole>());
kernel.Bind<IConsumer<ConsoleCommand>>().ToMethod(ctx => ctx.Kernel.Get<StandardConsole>());