【问题标题】:StructureMap in multi-layer solution多层解决方案中的 StructureMap
【发布时间】:2015-06-25 12:32:42
【问题描述】:

在我的解决方案中,我有 3 个项目:WebAPI、BusinessLayer 和 DataLayer。

在 WebAPI 中,我将结构图配置为使用 DefaultRegistry:

public class DefaultRegistry : Registry 
{
    public DefaultRegistry() 
    {
        Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
            });
        For<Business.Interfaces.IBusinessClass>().Use(ctx => new Business.BusinessClass());
        For<Data.Interfaces.IDataClass>().Use(ctx => new Data.DataClass());            
    }
}

WebAPI 中的控制器类如下所示:

public class MyController : ApiController
{
    private readonly IBusinessClass _businessClass;

    public MyController(IBusinessClass businessClass)
    {
        _businessClass = businessClass;
    }

    public HttpResponseMessage Get(int id)
    {
        var success = _businessClass.DoSomething();
        return success ? Request.CreateResponse(HttpStatusCode.OK) :   Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Error"); 
    }
}

在这个例子中为 _businessClass 注入依赖就像一个魅力。

现在让我们看一下 BusinessClass 的实现:

public class BusinessClass : IBusinessClass
{
    private readonly IDataClass _dataClass;

    public BusinessClass(IDataClass dataClass)
    {
        _dataClass = dataClass;
    }

    public void DoSomething()
    {
        _dataClass.DoSomethingWithData();
    }
}

在此示例中,_dataClass 的依赖注入不起作用。构造函数中的 dataClass 参数为 null,因此 _dataClass 字段未正确初始化。我究竟做错了什么? 我要补充一点,BusinessClass 是在 BusinessLayer 项目中定义的,而 DataClass 是在 DataLayer 项目中定义的(这两个项目都是类库)。

【问题讨论】:

  • ctx =&gt; new Data.DataClass() 行怎么编译?您的问题中是否有第二个构造函数没有显示?
  • 这只是一个简化,所以帖子不会因为不必要的代码而臃肿。
  • 看来问题不在于结构图本身,而在于内部类的设计。很抱歉给您带来麻烦,并感谢您提供帮助。案件结案。

标签: c# asp.net-web-api structuremap


【解决方案1】:

在您的默认注册表中,您已经通过调用注册默认约定

scan.WithDefaultConventions(); 

所以这两个调用是多余的。

For<Business.Interfaces.IBusinessClass>().Use(ctx => new Business.BusinessClass());
For<Data.Interfaces.IDataClass>().Use(ctx => new Data.DataClass());   

就像 Kenneth 说的那样,您可能没有扫描 BusinessClass 所在的程序集。

public class DefaultRegistry : Registry 
{
    public DefaultRegistry() 
    {
        Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.AssemblyContainingType<BusinessClass>();
                scan.WithDefaultConventions();
            });            
    }
}

【讨论】:

    【解决方案2】:

    问题在于您的注册:

    您只是在扫描调用程序集(即 Web API 项目)。

    您还需要包括其他程序集(您可能需要调整名称):

    Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.Assembly("BusinessLayer");
                scan.Assembly("DataLayer");
                scan.WithDefaultConventions();
            });
    

    【讨论】:

    • 我尝试扫描 DefaultRegistry 中的所有其他程序集,但没有帮助。我可能会补充一点,当我尝试在 WebAPI 控制器中使用 IDataClass/DataClass 对象时,它运行良好。但是当我尝试在 DoSomething() 方法中使用业务中定义的另一个类时,它也不起作用。
    【解决方案3】:

    我已经通过在 StructureMap 中使用 Singleton 解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-08
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      • 1970-01-01
      • 2011-11-16
      相关资源
      最近更新 更多