ASP.NET核心。配置DI为不同接口获取同一个对象
ASP.NET Core. Configure DI to get the same object for different interfaces
我有中间件,可以做一些工作并创建对象。我需要将这个对象注入控制器。
到目前为止,我通过向 DI 添加一些工厂来创建额外层的解决方案,这些工厂通过从 context.Items['myobject_created_and_placed_here_in_middleware']
中提取已经创建的对象来创建此类对象。
我也在考虑另一种方式:
public interface IReader
{
string Get();
}
public interface IWriter
{
string Set(string value);
}
public class Object1 : IReader, IWriter
{
public string s1 { get; set; }
public string Get()
{
return this.s1;
}
public string Set(string value)
{
this.s1 = value;
return s1;
}
}
public class Middleware1
{
RequestDelegate next;
private readonly IReader _reader;
public Middleware1(RequestDelegate next, IReader reader)
{
this.next = next;
_reader = reader;
}
public async Task Invoke(HttpContext context)
{
var test1 = _reader.Get();
await next.Invoke(context);
}
}
public class Middleware2
{
RequestDelegate next;
private readonly IWriter _writer;
public Middleware2(RequestDelegate next, IWriter writer)
{
this.next = next;
_writer = writer;
}
public async Task Invoke(HttpContext context)
{
_writer.Set("13168AAE-C886-453E-B655-ECE5D14645D9");
await next.Invoke(context);
}
}
Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
app.UseMiddleware<Middleware2>();
app.UseMiddleware<Middleware1>();
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
目前还不行。
这 returns 个不同的对象:
services.AddScoped<IReader,Object1>();
services.AddScoped<IWriter, Object1>();
这无法解析接口:
services.AddScoped<Object1>();
问题是:如何将其注册到DI中,并为每个请求的不同接口获取相同的对象。
就我个人而言,我会坚持使用 HttpContext
中的 Items
属性,因为它的唯一目的是存储请求范围内的项目。
但是,如果您想在 DI 中使用对象实例,我建议您将 IReader
和 IWriter
合并到一个接口中,并将其添加到 DI 容器中。
仅供参考:在 DI 注册之间共享单个对象是可能的,甚至在 Scoped
和 Transient
注册之间也是如此。尽量避免。
public interface IGodObject { } //empty marker interface
public interface IWriter { }
public interface IReader { }
public class GodObject : IGodObject, IReader, IWriter { }
services.AddScoped<IGodObject>(p =>
{
return new GodObject();
});
services.AddScoped<IReader>(p =>
{
return p.GetService<IGodObject>() as IReader;
});
services.AddScoped<IWriter>(p =>
{
return p.GetService<IGodObject>() as IWriter;
});
我有中间件,可以做一些工作并创建对象。我需要将这个对象注入控制器。
到目前为止,我通过向 DI 添加一些工厂来创建额外层的解决方案,这些工厂通过从 context.Items['myobject_created_and_placed_here_in_middleware']
中提取已经创建的对象来创建此类对象。
我也在考虑另一种方式:
public interface IReader
{
string Get();
}
public interface IWriter
{
string Set(string value);
}
public class Object1 : IReader, IWriter
{
public string s1 { get; set; }
public string Get()
{
return this.s1;
}
public string Set(string value)
{
this.s1 = value;
return s1;
}
}
public class Middleware1
{
RequestDelegate next;
private readonly IReader _reader;
public Middleware1(RequestDelegate next, IReader reader)
{
this.next = next;
_reader = reader;
}
public async Task Invoke(HttpContext context)
{
var test1 = _reader.Get();
await next.Invoke(context);
}
}
public class Middleware2
{
RequestDelegate next;
private readonly IWriter _writer;
public Middleware2(RequestDelegate next, IWriter writer)
{
this.next = next;
_writer = writer;
}
public async Task Invoke(HttpContext context)
{
_writer.Set("13168AAE-C886-453E-B655-ECE5D14645D9");
await next.Invoke(context);
}
}
Startup.cs:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
app.UseMiddleware<Middleware2>();
app.UseMiddleware<Middleware1>();
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
});
}
目前还不行。
这 returns 个不同的对象:
services.AddScoped<IReader,Object1>();
services.AddScoped<IWriter, Object1>();
这无法解析接口:
services.AddScoped<Object1>();
问题是:如何将其注册到DI中,并为每个请求的不同接口获取相同的对象。
就我个人而言,我会坚持使用 HttpContext
中的 Items
属性,因为它的唯一目的是存储请求范围内的项目。
但是,如果您想在 DI 中使用对象实例,我建议您将 IReader
和 IWriter
合并到一个接口中,并将其添加到 DI 容器中。
仅供参考:在 DI 注册之间共享单个对象是可能的,甚至在 Scoped
和 Transient
注册之间也是如此。尽量避免。
public interface IGodObject { } //empty marker interface
public interface IWriter { }
public interface IReader { }
public class GodObject : IGodObject, IReader, IWriter { }
services.AddScoped<IGodObject>(p =>
{
return new GodObject();
});
services.AddScoped<IReader>(p =>
{
return p.GetService<IGodObject>() as IReader;
});
services.AddScoped<IWriter>(p =>
{
return p.GetService<IGodObject>() as IWriter;
});