gpt4 book ai didi

c# - 为什么我必须在 ASP.NET MVC 中进行 "wire up"依赖注入(inject)?

转载 作者:太空狗 更新时间:2023-10-29 23:12:54 25 4
gpt4 key购买 nike

我认为接口(interface)、多态性和通过依赖注入(inject)实现控制反转等模式的全部原因是为了避免紧耦合、分离、模块化等。

为什么我必须像在 ASP.NET 中那样显式地将接口(interface)“连接”到具体类?我让注册表不是某种耦合吗?喜欢,

services.AddTransient<ILogger, DatabaseLogger>();

如果我使用一个记录器 ILogger,并创建一个实现该接口(interface)的文件和数据库类会怎么样。

在我的 IoC 中,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
public interface ILogger
{
void logThis(string message);

}
public class DatabaseLogger : ILogger
{
public void logThis(string message)
{
//INSERT INTO table.....
System.Console.WriteLine("inserted into a databse table");
}

}
public class FileLogger : ILogger
{
public void logThis(string message)
{
System.Console.WriteLine("logged via file");
}

}
public class DemoClass
{
public ILogger myLogger;


public DemoClass(ILogger myLogger)
{
this.myLogger = myLogger;
}
public void logThis(string message)
{
this.myLogger.logThis(message);
}

}
class Program
{

static void Main(string[] args)
{
DemoClass myDemo = new DemoClass(new DatabaseLogger()); //Isn't this Dependency Injection?
myDemo.logThis("this is a message");
Console.ReadLine();

}
}
}

那么为什么我必须注册或“连接”任何东西?这不是通过构造函数进行依赖注入(inject)吗(我是不是有根本性的误解)?我可以将任何实现 ILogger 的记录器放在那里。

我会创建其中两个吗?

services.AddTransient<ILogger, DatabaseLogger>();
services.AddTransient<ILogger, FileLogger>();

最佳答案

你实际上会进一步抽象它。在您的代码中,您将创建一个工厂。

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Example Factory Method

所以你本质上会有以下内容:

// Interface:
public interface ILogger : IDisposable
{
void Log<TEntity>(TEntity entity);
}

// Concrete Implementation:
public class DatabaseLogger : ILogger
{
public void Log<TEntity>(TEntity entity)
{
throw new NotImplementedException();
}
}

public class TextLogger : ILogger
{
public void Log<TEntity>(TEntity entity)
{
throw new NotImplementedException();
}
}

使用当前的定义方式,您将收到以下 IEnumerable<ILogger>当您将两个依赖项都连接到您的容器时。但是,为了正确包装它,我们将执行以下操作:

public interface ILoggerFactory
{
ILogger CreateDbLogger();

ILogger CreateLogger();
}

public class LoggerFactory : ILoggerFactory
{
public ILogger CreateDbLogger() => new DatabaseLogger();

public ILogger CreateLogger() => new TextLogger();
}

所以当我们注册我们的 Factory 时在我们的依赖注入(inject)中,我们会简单地写 services.AddTransient<ILoggerFactory, LoggerFactory>(); .注入(inject)工厂时,您只需使用:

public class Example
{
public ILoggerFactory Factory { get; }
public Example(ILoggerFactory factory)
{
Factory = factory;
}


// Utilize in a method.
using(var logger = Factory.CreateDbLogger())
logger.Log(...);

// Utilize in a method.
using(var logger = Factory.CreateLogger())
logger.Log(...);
}

现在,这可能会导致过度曝光。但希望这能澄清经常使用的依赖注入(inject)的用法。您可以通过键入“工厂模式”或“工厂方法”来阅读更多内容。

关于c# - 为什么我必须在 ASP.NET MVC 中进行 "wire up"依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41231520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com