在我的解决方案中,我有三个这样的项目。
我将Common.dll和Service.dll复制到d:\ libs这样的文件夹中,并将以下代码用于扫描类型
ObjectFactory.Initialize(x =>
{
x.Scan(xx =>
{
xx.AssembliesFromPath(@"d:\libs");
xx.LookForRegistries();
});
});
//I have PersonService that implement IPersonService
namespace Common
{
public interface IPersonService
{
string SayHello(string name);
}
}
namespace Services
{
public class PersonService : IPersonService
{
public string SayHello(string name)
{
return string.Format("Hello {0}", name);
}
}
}
当我想从IPerson获取实例时初始化我的依赖项后,我收到此错误
var personService = ObjectFactory.GetInstance<IPersonService>();
{&#34;没有注册默认实例,无法自动确定类型&#39; Common.IPersonService&#39; \ r \ n \ r \ n \ n没有为Common.IPersonService指定配置\ r \ n \ r \ n1。)Container.GetInstance(Common.IPersonService)\ r \ n&#34;}
答案 0 :(得分:2)
xx.WithDefaultConventions();
。d:\libs
文件夹。换句话说,当前的应用程序域不应该有任何程序集的2个实例。因此,如果您想直接在主机程序中使用IPersonService
界面,请添加对Common.dll
的引用,并且不要将其复制到d:\libs
文件夹以避免重复。现在主持人项目也不应该引用Services.dll
。答案 1 :(得分:1)
您可以在WithDefaultConventions()
的来电中使用Scan
,DefaultConventionScanner
会在内部使用var interfaceName = "I" + concreteType.Name;
return concreteType.GetInterfaces().FirstOrDefault(t => t.Name == interfaceName);
。
您可以阅读源代码或查看文档,但它会这样做:
IFooService
在默认约定扫描期间,扫描的每个具体类型将查找以字母“I”开头的类名的第一个接口。因此,在扫描过程中,FooService
会在扫描过程中找到For<IFooService>().Use<FooService>()
时自动注册并分配,因此您无需明确说明
{{1}}
当您没有为您请求的类型注册具体实现时,将始终抛出您看到的异常。
答案 2 :(得分:0)
您希望注册的类型不是因为您正在使用 xx.LookForRegistries()查找StructureMap注册表(您可以在此处阅读有关注册表的更多信息 - http://structuremap.github.io/registration/registry-dsl/)。如果您使用适当的注册创建此类注册表,那么SM将找到它们并注册。
如前所述,altrernative是使用 xx.WithDefaultConventions()。使用默认约定时,请查看此边缘情况,未注册预期类型 - https://stackoverflow.com/a/27449018/4336786