我一直在学习DI而且我已经实现了一些东西,但我想确定我的实现是否符合DI规则:
带有签名的界面:
public interface IDashboardRepository
{
public object sumAndAVG(string regionalManager, string dtFrom, string dtTo);
}
实现接口签名的类:
public class DashboardRepo:IDashboardRepository
{
private string cn = System.Configuration.ConfigurationManager.ConnectionStrings["MyDB"].ConnectionString;
NpgsqlConnection con = null;
public object sumAndAVG(string regionalManager, string dtFrom, string dtTo)
{
DataTable dt_sumProAval = new DataTable();
NpgsqlDataAdapter SumOfProduction = new NpgsqlDataAdapter(@"TheSQL is here since its long not part of the topic i removed it", cn);
SumOfProduction.Fill(dt_production);
var sumAndAvail = (from DataRow dr in dt_production.Rows
select new AverageSumViewModel
{
avg = Convert.ToDouble(dr["avalability"] == DBNull.Value ? 0.0 : dr["avalability"]),
}).ToList();
return sumAndAvail;
}
}
在我的控制器的最后,我使用它:
_idashboard.sumAndAVG( regionalManager, dtFrom, dtTo);
请告诉我,如果我正确的方向
答案 0 :(得分:1)
在我看来,你不需要你的DashboradHandeler
- 你可以在自己的构造函数中将接口注入特定的控制器。此外,您正在使用new
,这不是DI希望您做的;)
这样,您始终可以在控制器中拥有所需的接口。
考虑使用DashboradHandeler
的数十个/数百个控制器:您将无法知道DashboradHandeler
中使用的所有接口。并且所有控制器都强烈依赖于该类...
答案 1 :(得分:1)
你已经关闭了,但是你想要把它设置得更像:
public class DashboradHandeler
{
private readonly IDashboardRepository _idashboard;
public DashboradHandeler(IDashboardRepository idashboard)
{
this._idashboard = idashboard;
}
}
然后使用这样的东西。我正在包装注入的班级'这里的方法用于说明目的,而不是因为它是必需的。这不是一个理想的DI方式,但应该帮助你。
DashboradHandeler dashboard = new DashboradHandeler(new DashboardRepo());
dashboard.sumAndAVG(regionalManager,dtFrom,dtTo);
// This is in your DashboradHandeler class
public object sumAndAVG(string regionalManager, string dtFrom, string dtTo)
{
_idashboard(sumAndAVG(regionalManager,dtFrom,dtTo));
}
答案 2 :(得分:1)
见这个例子:
你的控制器
public IGetService iGetService { get; set; }
public HomeController() { }
public HomeController(IGetService iGetService)
{
this.iGetService = iGetService;
}
现在,如果您的控制器中的任何操作想要从该界面调用方法,您只需执行以下操作:
public void MyAction()
{
var myVar = iGetService.GetAllFromDataBase();
}
答案 3 :(得分:1)
这就是我对依赖注入和控制反转的理解:
"简单来说,依赖注入是对a的实现 IOC模式。而不是紧密耦合一个对象的依赖关系 另一个使用' new'关键字,将其作为外部依赖项传递 使用构造函数/属性/方法注入"。
有关详细信息,请参阅此处 - https://martinfowler.com/articles/injection.html
提出您的问题,您已在代码中使用构造函数注入实现了模式
<强>接口强>:
public interface IDashboardRepository
{
public object sumAndAVG(string regionalManager, string dtFrom, string dtTo);
}
<强>实施强>
public class DashboardRepo:IDashboardRepository
{
//Simplified for understanding
}
将IDashboardRepository用于另一个对象:
public class DashboradHandeler
{
public IDashboardRepository _idashboard;
public DashboradHandeler(IDashboardRepository _idashboard)
{
this._idashboard = _idashboard;
}
}
在另一个对象(您的控制器)中使用DashboradHandeler:
DashboradHandeler dashboard = new DashboradHandeler(new DashboardRepo());
dashboard._idashboard.sumAndAVG(regionalManager,dtFrom,dtTo);
<强>观察强>:
将 IDashboardRepository 注入 DashboradHandeler 类是 松散耦合。它颠倒了对象创造的责任 从 DashboradHandeler 到调用者的 IDashboardRepository 类。在 你的情况,它是 DashboradHandeler 。
然而,实例化
DashboradHandeler类可以修改。您可以将对象创建反转到外部容器(如Autofac,Ninject),而不是执行:DashboradHandeler dashboard = new DashboradHandeler(new DashboardRepo());
。避免使用&#39; new&#39;关键字,只要适用。
可以改进命名约定。 &#39; _&#39;符号主要用于私有财产。使用其中一个而不是两个:
您的代码:
public class DashboradHandeler
{
public IDashboardRepository _idashboard;
public DashboradHandeler(IDashboardRepository _idashboard)
{
this._idashboard = _idashboard;
}
}
使用&#39; _&#39;符号强>:
public class DashboradHandeler
{
private IDashboardRepository _idashboard;
public DashboradHandeler(IDashboardRepository idashboard)
{
_idashboard = idashboard;
}
}
没有&#39; _&#39;符号强>:
public class DashboradHandeler
{
private IDashboardRepository idashboard;
public DashboradHandeler(IDashboardRepository idashboard)
{
this.idashboard = idashboard;
}
}
这些是我现在能想到的几点。