我试图避免在我的主项目中引用具体类型库,但我收到此错误:
No default instance or named instance 'Default' for requested plugin type StackExchangeChatInterfaces.IClient
1.) Container.GetInstance(StackExchangeChatInterfaces.IClient ,{username=; password=; defaultRoomUrl=; System.Action`2[System.Object,System.Object]=System.Action`2[System.Object,System.Object]})
我已经设置了我的容器来扫描程序集,如下所示:
var container = new Container(x =>
{
x.Scan(scan =>
{
scan.AssembliesFromApplicationBaseDirectory();
scan.ExcludeNamespace("StructureMap");
scan.WithDefaultConventions();
scan.AddAllTypesOf<IMessageHandlers>();
});
//x.For<IClient>().Use<Client>(); //GetInstance will work if this line is not commented out.
});
当我尝试获取实例时,出现错误,用于获取实例的代码如下所示:
chatInterface = container
.With("username").EqualTo(username)
.With("password").EqualTo(password)
.With("defaultRoomUrl").EqualTo(roomUrl)
.With<Action<object, object>>(delegate(object sender, object messageWrapper)
{
string message = ((dynamic)messageWrapper).Message;
Console.WriteLine("");
Console.WriteLine(message);
foreach (var item in messageHandlers)
{
item.MessageHandler.Invoke(message, chatInterface);
}
}).GetInstance<IClient>();
如果我显式地将具体类映射到接口,一切都很笨拙,但这意味着我需要引用Client
所在的项目,这是我不想做的。
这真的很有趣。看起来默认约定无法向此类构造函数注册类型(在版本 2.6.3 和 3+ 上都尝试过)。我仅在仅指定无参数构造函数时才注册。查看两个版本的来源,确实值得怀疑,因为它应该注册。需要更深入地了解代码...
无论如何,请尝试使用自定义注册约定:
public class ClientConvention : IRegistrationConvention
{
public void Process(Type type, Registry registry)
{
if (type.IsClass && !type.IsAbstract && !type.IsGenericType &&
type.GetInterfaces().Contains(typeof(IClient)))
{
registry.For(typeof(IClient)).Use(type);
}
}
}
像这样配置它:
var container = new Container(
c => c.Scan(
s =>
{
s.ExcludeNamespace("StructureMap");
s.WithDefaultConventions();
s.Convention<ClientConvention>();
s.AddAllTypesOf<IMessageHandlers>();
}));
这应该可以正常工作。
默认类型扫描不会选取构造函数包含字符串、数字或日期等基元参数的具体类型。这种想法是,无论如何,您实际上都必须显式配置这些内联依赖项。
"但这意味着我需要参考客户所在的项目,我不想这样做。
- 这真的重要吗?我认为您通过尝试消除程序集引用使事情变得比必须的更难。