2

在我的解决方案中,我有三个这样的项目。 在此处输入图像描述

我将 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>();

{"未注册默认实例且无法自动确定类型 'Common.IPersonService'\r\n\r\n没有为 Common.IPersonService 指定配置\r\n\r\n1.) Container.GetInstance(Common .IPersonService)\r\n"}

4

3 回答 3

2
  • 也添加xx.WithDefaultConventions();
  • 当您使用 StructureMap 设计插件系统时,宿主项目不应引用任何插件。只有接口/合同插件应该被引用,并且这个程序集不应该被复制到d:\libs文件夹中。换句话说,当前应用程序域不应该有任何程序集的 2 个实例。所以如果要IPersonService直接在宿主程序中使用接口,请添加引用Common.dll,不要复制到d:\libs文件夹,以免重复。现在宿主项目也不应该有参考Services.dll
于 2014-12-19T20:25:53.223 回答
1

您可以WithDefaultConventions()在您的调用中使用Scan,内部将使用DefaultConventionScanner.

您可以阅读源代码或查看文档,但它会这样做:

var interfaceName = "I" + concreteType.Name;
return concreteType.GetInterfaces().FirstOrDefault(t => t.Name == interfaceName);

在默认约定扫描期间,扫描的每个具体类型都将查找类名的第一个接口,该接口前面带有字母“I”。因此,在扫描时,IFooService如果在扫描过程中发现,将自动注册和分配FooService,因此您不必明确说明

For<IFooService>().Use<FooService>()

当您请求的类型没有注册的具体实现时,您看到的异常将始终被抛出。

于 2014-12-19T20:54:17.723 回答
0

您希望注册的类型不是因为您正在使用xx.LookForRegistries()进行扫描,它会查找 StructureMap 注册表(您可以在此处阅读有关注册表的更多信息 - http://structuremap.github.io/registration/registry-dsl/) . 如果您使用正确的注册创建此类注册表,则 SM 将找到它们并进行注册。

如前所述,替代方法是使用xx.WithDefaultConventions()。使用默认约定时查看此边缘情况,预期类型未注册 - h​​ttps://stackoverflow.com/a/27449018/4336786

于 2014-12-21T15:19:51.650 回答