在ASP.NET Core中,您可以使用Microsoft的依赖注入框架执行的操作之一是绑定"open generics"(未绑定到具体类型的泛型类型),如下所示:
public void ConfigureServices(IServiceCollection services) {
services.AddSingleton(typeof(IRepository<>), typeof(Repository<>))
}
Run Code Online (Sandbox Code Playgroud)
您还可以使用工厂模式来水合依赖项.这是一个人为的例子:
public interface IFactory<out T> {
T Provide();
}
public void ConfigureServices(IServiceCollection services) {
services.AddTransient(typeof(IFactory<>), typeof(Factory<>));
services.AddSingleton(
typeof(IRepository<Foo>),
p => p.GetRequiredService<IFactory<IRepository<Foo>>().Provide()
);
}
Run Code Online (Sandbox Code Playgroud)
但是,我还没弄清楚如何将这两个概念结合起来.看起来它会从这样的东西开始,但我需要用于水合实例的具体类型IRepository<>.
public void ConfigureServices(IServiceCollection services) {
services.AddTransient(typeof(IFactory<>), typeof(Factory<>));
services.AddSingleton(
typeof(IRepository<>),
provider => {
// Say the IServiceProvider is trying to hydrate
// IRepository<Foo> when this lambda is invoked.
// In that case, I need access to a System.Type
// object …Run Code Online (Sandbox Code Playgroud) 我一直很愉快地使用Ninject现在很长一段时间,我真的很喜欢它,但我面对的,因为释放一个艰难的选择ASP.NET 5和MVC 6.
基本上,微软已经发布了自己的依赖注入系统; 据我所知,这引起了很多批评.但我更大的问题在于它如何影响其他图书馆.
从我在网上提出的另一个问题和其他资源来看,似乎Ninject不能与MVC 6一起开箱即用.尽管有一个以详细库形式给出的"解决方案" Microsoft.Framework.DependencyInjection.Ninject and Ninject.这甚至比较棘手,因为该库需要添加https://www.myget.org/F/aspnetmaster/到您的NuGet提要列表中.
我做了一些挖掘,发现这个图书馆的托管地点; 它看起来不错,它似乎可以从我能说的工作中得到解决,但有一些事情让我感到困扰.
基本上,我非常担心这是某种乐队助手,对Ninject(甚至其他容器库)的支持正在消失.是否有一些隐藏的信息,我只是没有发现?
AutoFac 比 Microsoft.Extensions.DependencyInjection 好在哪里?Autofac 支持属性和方法注入(但是我真的不明白属性和方法注入可能有用的地方)。
我的意思是当我可以通过 Microsoft.Extensions.DependencyInjection 做同样的事情时,我为什么要使用 AutoFac
我的ASP.NET 5应用程序中有一个带有多个构造函数的标记助手.当ASP.NET 5尝试解析类型时,这会在运行时导致以下错误:
InvalidOperationException:在"MyNameSpace.MyTagHelper"类型中找到了接受所有给定参数类型的多个构造函数.应该只有一个适用的构造函数.
其中一个构造函数是无参数的,另一个构造函数的参数不是注册类型.我希望它使用无参数构造函数.
有没有办法让ASP.NET 5依赖注入框架选择一个特定的构造函数?通常这是通过使用属性完成的,但我找不到任何东西.
我的用例是我正在尝试创建一个既是TagHelper的单个类,也是一个HTML帮助器,如果这个问题得到解决,这个完全有可能.
我正在尝试在基于 .NET Core 2.1 的 C# 控制台应用程序中登录并运行。
我在 DI 声明中添加了以下代码:
var sc = new ServiceCollection();
sc.AddLogging(builder =>
{
builder.AddFilter("Microsoft", LogLevel.Warning);
builder.AddFilter("System", LogLevel.Warning);
builder.AddFilter("Program", LogLevel.Warning);
builder.AddConsole();
builder.AddEventLog();
});
Run Code Online (Sandbox Code Playgroud)
我试图通过在服务Microsoft.Extensions.Logging.ILogger的构造函数中使用接口来注入服务,但出现以下错误:
未处理的异常:System.InvalidOperationException:尝试激活“MyService”时无法解析“Microsoft.Extensions.Logging.ILogger”类型的服务。
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, CallSiteChain callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateConstructorCallSite(ResultCache lifetime, Type serviceType, Type implementationType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(ServiceDescriptor descriptor, Type serviceType, CallSiteChain callSiteChain, Int32 slot)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.TryCreateExact(Type serviceType, CallSiteChain callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateCallSite(Type serviceType, CallSiteChain callSiteChain)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteFactory.CreateArgumentCallSites(Type serviceType, Type implementationType, …Run Code Online (Sandbox Code Playgroud) 我试图进入新的ASP.NET MVC 6的东西,但我很难用他们的新DI系统.我试图在线查找资源,但我找到的所有内容仅涵盖使用它的绝对最低限度.
我之前使用的是Ninject,我有几个这样工作的连线:
Bind<IDocumentStore>()
.ToMethod(c => CreateDocumentStore())
.InSingletonScope();
private static IDocumentStore CreateDocumentStore() {
// lots of initialization code, etc.
return documentStore;
}
Run Code Online (Sandbox Code Playgroud)
但到目前为止,我很难找到如何将这种行为转化为微软的新DI系统.我能找到的只是这样的例子:
services.AddTransient<IEmailSender, AuthMessageSender>();
services.AddTransient<ISmsSender, AuthMessageSender>();
Run Code Online (Sandbox Code Playgroud)
和:
services.AddMvc();
Run Code Online (Sandbox Code Playgroud)
一切似乎完全在目标服务的默认构造函数上工作.有没有办法在这个新的DI系统中产生我需要的行为?
我见过了
services.Configure<TOptions>(options => {});
Run Code Online (Sandbox Code Playgroud)
但我不清楚这是否会影响我的想法,或者它是否留给特定的行为.
我是Repository和DI的新手,并试图在我的MVC 5项目中实现.
我实现了构造函数注入,在我的控制器中有一个像这样的构造函数:
IBook _ibook;
public Test(IBook ibook)
{
_ibook = ibook;
}
Run Code Online (Sandbox Code Playgroud)
没有任何DI库,它会抛出一个错误:没有空构造函数.
为了避免这种情况,我又添加了一个构造函数,如下所示:
public Test ():this(new Book())
{
}
Run Code Online (Sandbox Code Playgroud)
由于我是DI的新手,我不想通过使用DI库冒险我的项目,后来可能会抛出一些我可能无法解决的错误.
我想知道如果我不使用DI库会遇到什么问题.
如果推荐,哪个DI库适合初学者?我见过很少有NInject和Unity的视频.
asp.net-mvc design-patterns dependency-injection ninject unity-container
可以手动注册依赖项:
services.AddTransient<IEmailService, EmailService>();
services.AddTransient<ISmsService, SmsService>();
Run Code Online (Sandbox Code Playgroud)
当依赖关系太多时,手动注册所有依赖项变得很困难.
在MVC 6(beta 7)中实现基于约定的绑定的最佳方法是什么?
PS在我以前使用的项目Ninject有ninject.extensions.conventions.但我找不到适用于MVC 6的Ninject适配器.
c# dependency-injection ninject asp.net-core-mvc asp.net-core
我正在使用 ASP.NET.Core 将 Web 服务器嵌入到大型遗留桌面应用程序中。我的中间件组件需要引用预先存在的应用程序对象。
我很困难地使用本机 DI 容器完成了这项工作,但生成的代码非常迟钝和不透明。
我真正想做的是通过构造函数参数显式注入依赖项,这些依赖项是特定的预先存在的对象实例。DI 容器的自动魔法并没有给我任何好处,只是给我带来了很多痛苦!
是否可以在没有 DI 容器的情况下使用 ASP.NET.Core?
下面是一些简化的代码来说明我当前的解决方案:
class Dependency
{
public string Text { get; }
public Dependency(string text) => Text = text;
}
class MyMiddleware
{
private readonly RequestDelegate _next;
private readonly Dependency _dep1;
private readonly Dependency _dep2;
public MyMiddleware(RequestDelegate next, Dependency dep1, Dependency dep2)
{
_next = next;
_dep1 = dep1;
_dep2 = dep2;
}
public Task InvokeAsync(HttpContext context)
{
return context.Response.WriteAsync(_dep1.Text + _dep2.Text);
}
}
Run Code Online (Sandbox Code Playgroud)
启动和应用代码:
class Startup
{ …Run Code Online (Sandbox Code Playgroud) c# dependency-injection asp.net-core asp.net-core-middleware asp.net-core-2.0
我正在尝试编写一个ASP.NET Core 2.2集成测试,该测试安装程序将装饰一个特定的服务,该服务通常作为依赖项可用于API。装饰器将为我提供一些集成测试所需的其他功能,以拦截对基础服务的调用,但由于当前的设置,我似乎无法正确地装饰中的普通服务ConfigureTestServices:
Microsoft.Extensions.DependencyInjection.Abstractions.dll中发生类型'System.InvalidOperationException'的异常,但未在用户代码中处理
没有注册类型'Foo.Web.BarService'的服务。
为了重现这一点,我刚刚使用VS2019创建了一个新的ASP.NET Core 2.2 API Foo.Web项目...
// In `Startup.cs`:
services.AddScoped<IBarService, BarService>();
Run Code Online (Sandbox Code Playgroud)
public interface IBarService
{
string GetValue();
}
Run Code Online (Sandbox Code Playgroud)
public class BarService : IBarService
{
public string GetValue() => "Service Value";
}
Run Code Online (Sandbox Code Playgroud)
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IBarService barService;
public ValuesController(IBarService barService)
{
this.barService = barService;
}
[HttpGet]
public ActionResult<string> Get()
{
return barService.GetValue();
}
}
Run Code Online (Sandbox Code Playgroud)
...和同伴的xUnit Foo.Web.Tests项目,我利用WebApplicationfactory<TStartup> ......
public class DecoratedBarService : IBarService
{ …Run Code Online (Sandbox Code Playgroud) asp.net-core ×5
c# ×5
ninject ×3
.net-core ×2
asp.net-mvc ×2
asp.net ×1
autofac ×1
generics ×1
logging ×1
xunit ×1