Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.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# NET内核。配置DI以获得不同接口的相同对象_C#_Asp.net Core_Asp.net Core Mvc_Asp.net Core Webapi - Fatal编程技术网

C# NET内核。配置DI以获得不同接口的相同对象

C# NET内核。配置DI以获得不同接口的相同对象,c#,asp.net-core,asp.net-core-mvc,asp.net-core-webapi,C#,Asp.net Core,Asp.net Core Mvc,Asp.net Core Webapi,我有中间件,它做一些工作并创建对象。我需要将这个对象注入控制器。 到目前为止,我看到的解决方案是通过在DI中添加一些工厂,这些工厂通过从上下文中提取已经创建的对象来创建这样的对象 我也在考虑另一种方式: public interface IReader { string Get(); } public interface IWriter { string Set(string value); } public class Object1 : IReader, IWriter

我有中间件,它做一些工作并创建对象。我需要将这个对象注入控制器。 到目前为止,我看到的解决方案是通过在DI中添加一些工厂,这些工厂通过从
上下文中提取已经创建的对象来创建这样的对象

我也在考虑另一种方式:

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!");
        });
    }
public void配置(IApplicationBuilder应用程序、IHostingEnvironment环境、iLogger工厂)
{
loggerFactory.AddConsole();
app.UseMiddleware();
app.UseMiddleware();
app.Run(异步(上下文)=>
{
wait context.Response.WriteAsync(“Hello World!”);
});
}
到目前为止,它还不起作用。
这将返回不同的对象:

services.AddScoped<IReader,Object1>();
services.AddScoped<IWriter, Object1>();
services.addScope();
services.addScope();
这无法解析接口:

services.AddScoped<Object1>();
services.addScope();

问题是:如何在DI中注册它,并为每个请求的不同接口获取相同的对象。

我个人会坚持使用
HttpContext
中的
Items
属性,因为它的唯一目的是存储请求范围内的项


但是,如果您想在DI中使用对象实例,我建议您将
IReader
IWriter
合并到一个接口中,并将其添加到DI容器中。

FYI:可以在DI注册之间共享一个对象,甚至在
范围内的
暂时的
注册之间。如果可能的话,尽量避免

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;
});
公共接口IGodObject{}//空标记接口
公共接口IWriter{}
公共接口IReader{}
公共类GodObject:IGodObject、IReader、IWriter{}
services.AddScoped(p=>
{
返回新的GodObject();
});
services.AddScoped(p=>
{
返回p.GetService()作为IReader;
});
services.AddScoped(p=>
{
将p.GetService()作为IWriter返回;
});

工厂实际上是您唯一的选择,因为大多数DI容器都是围绕对象的类型标识设计的。如果给它两种类型,它将创建两个不同的对象。这就是DI容器存在自定义工厂调用的原因,因为有时自动化的简单方法并不适用于所有情况。@juunas我相信不是这样。我正在询问如何将中间件中创建的对象传递给控制器,并提出了一些想法。因为这个对象应该根据请求创建(贯穿整个管道),所以我在这里看不到重复。嗯,没错。我可能有点草率地使用了这个标志。因此,我可以创建
接口ICompose:IReader,IWriter
。然而,我应该(??)在我的控制器/中间件中使用这个
ICompose
,然后使用casting(但它没有任何意义)。我想避免这样的事情。因为没有人能从口袋里得到答案,我想我的逻辑不是很流行,所以asp.net内核不支持标准的逻辑,所以我不得不使用Items。很好的提示。这应该被标记为答案。您还可以通过删除大括号和“return”关键字使所有这些注册成为一行。而且,第一次注册可以是
services.addScope()