Skip to main content
 首页 » 编程设计

c#之多层解决方案中的 StructureMap

2024年02月06日28jpfss

在我的解决方案中,我有 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 中的 Controller 类如下所示:

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 注入(inject)依赖项就像一个魅力。

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

public class BusinessClass : IBusinessClass 
{ 
    private readonly IDataClass _dataClass; 
 
    public BusinessClass(IDataClass dataClass) 
    { 
        _dataClass = dataClass; 
    } 
 
    public void DoSomething() 
    { 
        _dataClass.DoSomethingWithData(); 
    } 
} 

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

请您参考如下方法:

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

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(); 
            });             
    } 
}