我不确定这是否可行,但这里有。我正在使用Simple Injector并将我的服务接口注入到我的apiControllers中。一切都很好。
我有一个可以使用不同网址调用的控制器,例如可以使用这些网址中的每个网址调用
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
}
我是Simple Injector的新手,所以不确定是谁,或者即使你可以在每个网络请求的基础上注入这个词?因此,每次创建控制器时,都会注入一个新服务,但该字可能不同......
这可能吗,或者有人知道有更好的方法吗?
正如我所说,我使用的是C#,ASP.NET WebApi和Simple Injector。
答案 0 :(得分:3)
我想我最好能直接注入这个词 进入我的服务。
不,你绝对不应该这样做。此word
是运行时值(它是特定于请求的),您的对象图(您允许Simple Injector构建的服务)不应包含任何运行时数据。运行时数据应该通过方法调用。
我认为@Trevor是正确的,虽然我不同意他的实现,因为你的业务层不应该硬连接到你的演示框架。
相反,您应该将该单词的检索放在抽象之后,让它称之为IWordService
。这意味着MyService
将如下所示:
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
定义如下:
public interface IWordService {
string CurrentWord { get; }
}
此界面显然应位于业务层程序集或业务层所依赖的程序集中。
使用@Trevor提供的代码,我们可以创建一个ASP.NET特定的实现,如下所示:
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 API项目或其相关程序集中。这门课程的注册很简单:
container.RegisterSingleton<IWordService>(new AspNetWordService());
也许,这个AspNetWordService
实现可能不会完全按照您的意愿执行,但它不应该很难改变它。更改此课程不会影响系统的任何部分。
答案 1 :(得分:1)
您可以执行类似
的操作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);
}
}
答案 2 :(得分:0)
您可以在服务方法中查看请求网址并从中找出:
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);
}