首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >简单注入器-向服务构造函数中注入url值

简单注入器-向服务构造函数中注入url值
EN

Stack Overflow用户
提问于 2015-05-15 14:56:13
回答 3查看 1.1K关注 0票数 2

我不知道这是否可能,但现在开始了。我使用简单的注入器并将我的服务接口注入到我的apiControllers中。都很好。

我有一个控制器,可以使用不同的urls调用,例如,它可以被称为be使用这些urls中的每一个。

代码语言:javascript
复制
http://localhost/api/company
http://localhost/api/contact
http://localhost/api/cabbage

现在我需要知道最后一个词是什么,并在我的服务中使用它。

目前,我有一个简单的界面,如下所示

代码语言:javascript
复制
public interface IMyService() {
    MyObject Get(long id);
}

然后我的基本服务实现了这个服务

代码语言:javascript
复制
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控制器如下所示

代码语言:javascript
复制
[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);
    }    
}

我在想,如果我能把这个词直接注入到我的服务中,那将是最好的。因此,我必须将服务构造函数更改为如下

代码语言:javascript
复制
public MyService(IDbContext context, string theWord) {
    _context = context;
    // now I can store the word and use it in my service
}

我是一个简单的喷射器新手,所以不确定是谁,甚至是你是否可以在每个web请求的基础上注入这个词?因此,每次创建控制器时,都会注入一个新的服务,但是这个词可能是不同的.

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

正如我所说的,我使用的是C#、ASP.NET WebApi和简单注入器。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-15 15:26:18

我在想,如果我能把这个词直接注入到我的服务中,那将是最好的。

不,你绝对不应该这么做。这个word是一个运行时值(它是特定于请求的),您的对象图(让简单的注入器构建的服务)不应该包含任何运行时数据。运行时数据应该通过方法调用进行。

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

相反,您应该将该单词的检索放在抽象之后,我们将其命名为IWordService。这意味着MyService看起来如下:

代码语言:javascript
复制
public class MyService : IMyService {
    private IDbContext _context;
    private IWordService _wordService;

    public MyService(IDbContext context, IWordService wordService) {
        _context = context;
        _wordService = wordService;
    }

    public MyObject Get(long id) {
        string word = _wordService.CurrentWord;
        // etc.
    }
}

IWordService定义为:

代码语言:javascript
复制
public interface IWordService {
    string CurrentWord { get; }
}

这个接口显然应该位于您的业务层程序集中,或者您的业务层所依赖的程序集中。

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

代码语言:javascript
复制
public sealed class AspNetWordService : IWordService {
    public string CurrentWord {
        get {
            var requestUri = Request.RequestUri.AbsoluteUri;
            var theWord = requestUri.Substring(requestUri.LastIndexOf('/'));
            return theWord;
        }
    }
}

AspNetWordService是特定于ASP.NET的,显然应该放在Web项目或其相关程序集中。这类的注册很简单:

代码语言:javascript
复制
container.RegisterSingleton<IWordService>(new AspNetWordService());

也许,这个AspNetWordService实现可能做不到您想做的事情,但是更改它应该不会那么困难。更改这个类不会影响系统的任何部分。

票数 3
EN

Stack Overflow用户

发布于 2015-05-15 15:22:26

你可以做这样的事

代码语言:javascript
复制
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);
    }    
}
票数 1
EN

Stack Overflow用户

发布于 2015-05-15 15:03:48

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

代码语言:javascript
复制
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);
}  
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30262685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档