Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 简单注入器-将url值注入服务构造函数_C#_.net_Asp.net Web Api_Dependency Injection_Simple Injector - Fatal编程技术网

C# 简单注入器-将url值注入服务构造函数

C# 简单注入器-将url值注入服务构造函数,c#,.net,asp.net-web-api,dependency-injection,simple-injector,C#,.net,Asp.net Web Api,Dependency Injection,Simple Injector,我甚至不确定这是否可能,但事情是这样的。我正在使用简单的注入器,并将我的服务接口注入到我的APIController中。都很好 我有一个控制器,可以使用不同的URL调用,例如,可以使用这些URL中的每一个调用它 http://localhost/api/company http://localhost/api/contact http://localhost/api/cabbage 现在我需要知道最后一句话是什么,并在我的服务中使用它 目前我有一个简单的界面,就像这样 public inter

我甚至不确定这是否可能,但事情是这样的。我正在使用简单的注入器,并将我的服务接口注入到我的APIController中。都很好

我有一个控制器,可以使用不同的URL调用,例如,可以使用这些URL中的每一个调用它

http://localhost/api/company
http://localhost/api/contact
http://localhost/api/cabbage
现在我需要知道最后一句话是什么,并在我的服务中使用它

目前我有一个简单的界面,就像这样

public interface IMyService() {
    MyObject Get(long id);
}
然后是实现该服务的基本服务

public class MyService : IMyService {
    private IDbContext _context;

    public MyService(IDbContext context) {
        _context = context;
    }

    public MyObject Get(long id) {
        // here i need that word!!
        return _context.Database.RawQuery("SELECT * FROM something WHERE Id = " + id);
    }
}
现在,我的通用api控制器如下所示

[RoutePrefix("api/{myword}")]
public class MyController() {
    private IMyService _service;

    public MyController(IMyService service) {
        _service = service;
    }

    public Get(long id) {
        var model = Mapper.Map<ObjectModel>(_service.Get(id));

        return Ok(model);
    }    
}
public MyService(IDbContext context, string theWord) {
    _context = context;
    // now I can store the word and use it in my service
}
我不熟悉SimpleInjector,所以不确定是谁,甚至不确定您是否可以根据每个web请求注入该词?因此,每次创建控制器时,都会注入一个新的服务,但这个词可能会有所不同

这是可能的,还是有人知道有更好的方法


正如我所说,我正在使用C#、ASP.NET WebApi和Simple Injector。

您可以在服务方法中看到请求URL,并从中找到它:

public Get(long id)
{
    var requestUri = Request.RequestUri.AbsoluteUri;
    var theWord = requestUri.Substring(requestUri.LastIndexOf('/'));

    var model = Mapper.Map<ObjectModel>(_service.Get(theWord, id));

    return Ok(model);
}  
public Get(长id)
{
var requestUri=Request.requestUri.AbsoluteUri;
var theWord=requestUri.Substring(requestUri.LastIndexOf('/');
var model=Mapper.Map(_service.Get(theWord,id));
返回Ok(型号);
}  

您可以执行以下操作

public class MyController() {
    private IMyService _service;

    public MyController(IMyService service) {
        _service = service;
    }

    [Route("api/{serviceName}/{id}")] //url: api/myService/10
    //restful [Route("api/service/{serviceName}/id/{id}")]  //url: api/service/myService/id/10
    public Get(string serviceName, long id) {
        var model = Mapper.Map<ObjectModel>(_service.Get(id));

        return Ok(model);
    }    
}
公共类MyController(){
私人IMY服务;
公共MyController(IMyService服务){
_服务=服务;
}
[路由(“api/{serviceName}/{id}”)]///url:api/myService/10
//restful[Route(“api/service/{serviceName}/id/{id}”)]///url:api/service/myService/id/10
公共Get(字符串serviceName,长id){
var model=Mapper.Map(_service.Get(id));
返回Ok(型号);
}    
}
我在想,如果我能直接插入这个词,那将是最好的 为我服务

不,你绝对不应该这样做。这个
word
是一个运行时值(它是特定于请求的),您的对象图(您让Simple Injector构建的服务)不应该包含任何运行时数据。运行时数据应该通过方法调用流动

我认为@Trevor的方法是正确的,尽管我不同意他的实现,因为您的业务层不应该硬连接到您的表示框架

相反,您应该将该词的检索放在抽象之后,我们称之为
IWordService
。这意味着
MyService
将如下所示:

公共类MyService:IMyService{
私有上下文_上下文;
私人IWordService(IWordService);;
公共MyService(IDbContext上下文,IWordService wordService){
_上下文=上下文;
_wordService=wordService;
}
公共MyObject获取(长id){
字符串字=_wordService.CurrentWord;
//等等。
}
}
使用
IWordService
定义如下:

公共接口IWordService{
字符串CurrentWord{get;}
}
这个接口显然应该位于您的业务层程序集中,或者您的业务层所依赖的程序集中

使用@Trevor提供的代码,我们可以创建一个特定于ASP.NET的实现,如下所示:

公共密封类AspNetWordService:IWordService{
公共字符串当前字{
得到{
var requestUri=Request.requestUri.AbsoluteUri;
var theWord=requestUri.Substring(requestUri.LastIndexOf('/');
返回单词;
}
}
}
AspNetWordService
特定于ASP.NET,显然应该放在Web API项目或其相关程序集中。此类注册很简单:

container.RegisterSingleton(新的AspNetWordService());

也许,这个
AspNetWordService
实现可能并不能完全满足您的需求,但改变它应该不会太难。更改此类不会影响系统的任何部分。

谢谢您的回答,但有没有办法将其放入构造函数中?我问这个问题是因为在这个控制器上,我有更多的方法,而不仅仅是Get方法,而且我真的不想在每个叫做excellent answer的方法上都传递“theWord”,谢谢你给我指明了正确的方向