C#Web Api 2使用StructureMap将请求数据传递给注入的依赖构造函数参数

时间:2018-03-29 19:34:14

标签: structuremap webapi2

我正熟悉C#IoC框架。我选择了StructureMap.Webapi2来集成到现有的api中。 我有以下场景,我不确定最好的实现方式是什么。

public class MyController : ApiController
{
     public IHttpActionResult MyAction(string clientCode, [FromBody]MyDto bodyData)
    {
        var client = new ClientManager().GetClientByCode(clientCode);

        var someData = new SomeData
        {
            User = bodyData.User,
            ClientCode = clientCode,
            SomeField = client.SomeField
        };

        var myService = new WorkerService(someData);
        myService.DoSomething();

        return Ok();
    }
}

查看WorkerService:

public WorkerService(SomeData someData)
{
    _someData = someData;

    _someCollection = GetSomeData(); // GetSomeData uses _someData
}

public DoSomething()
{
    // some code that uses _someData and _someCollection
}

方法1:

  • 使WorkerService的构造函数无参数,并添加一个可在MyController MyAction中初始化的公共SomeData属性。
  • 然后,IoC可以将ClientManager和WorkerService注入构造函数中以添加到控制器中。

行动将如下:

public IHttpActionResult MyAction(string clientCode, [FromBody]MyDto bodyData)
{
    var client = _clientManager.GetClientByCode(clientCode);

    var someData = new SomeData
    {
        User = bodyData.User,
        ClientCode = clientCode,
        SomeField = client.SomeField
    };

    _myService.SomeData = someData;
    _myService.DoSomething();

    return Ok();
}

方法2(我不确定如何实施)

  • 保持WorkerService构造函数不变(带参数)。将服务注入Controller的构造函数(需要在运行时构建并传递服务的参数(SomeData),而不是让MyAction构建SomeData)。
  • 以某种方式构建SomeData(可能使用工厂)之前,每个请求都由控制器处理。这意味着ClientManager必须以某种方式/工厂注入。根据请求构建要注入控制器的WorkerService时,IoC将使用some / factory的输出。

对我来说,方法1似乎更快更简单,但方法2似乎更具吸引力,更具挑战性,并且有更多的学习。

1 个答案:

答案 0 :(得分:0)

我最终找到了解决问题的方法:

  1. 创建被动属性并添加到操作
  2. 创建一个ActionFilter,它检查属性,找到后,从请求中获取数据。
  3. 由于我不喜欢在ActionFilter中读取请求主体的方法,因此我更改了请求并将需要的数据从主体(服务器和数据库名称)移动到请求的URL。然后我为该数据创建了一个POCO,我将其注入ActionFilter并填充来自url的数据。 POCO isntance现在可以在需要它的依赖链中的每个服务中使用。
  4. 对于我在SomeData对象中需要的其余数据,我按照方法1,使WorkerService的构造函数无参数并传递数据,如:

    _myService.DoSomething(someData);
    
  5. 最后一招是将ActionFilter添加到config.Filters,因为我的过滤器有自己的依赖项,我不能这样做:

    config.Filters.add(new MyActionFilter(What_About_The_Parametes_???))
    
  6. 我必须获取structureMap的容器实例并让它返回我的过滤器的一个实例,这将导致所有依赖项被注入其中,然后我可以将过滤器实例添加到config.Filters:

        var container = StructuremapMvc.StructureMapDependencyScope.Container;
        config.Filters.Add(container.GetInstance<IMyActionFilter>());