Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.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# 如何使用接口的实现而不创建对实现的依赖?_C#_Asp.net_Webforms_Dependency Management_Solid Principles - Fatal编程技术网

C# 如何使用接口的实现而不创建对实现的依赖?

C# 如何使用接口的实现而不创建对实现的依赖?,c#,asp.net,webforms,dependency-management,solid-principles,C#,Asp.net,Webforms,Dependency Management,Solid Principles,我正试图利用我从学习坚实的原理中学到的知识来制作一个简单的ASP.NET网络表单 我已经将我的解决方案设置为3个项目:主asp.netwebforms项目、数据访问接口类库项目和数据访问类库项目(其中包含数据访问接口项目中接口的实现) 我在Data Access Interfaces程序集中有一个icoinstrage接口,看起来像这样(Coin只是Data Access Interfaces程序集中的一个DTO类): 我的问题是:如何在webforms项目中使用CoinSqlServerSto

我正试图利用我从学习坚实的原理中学到的知识来制作一个简单的ASP.NET网络表单

我已经将我的解决方案设置为3个项目:主asp.net
webforms
项目、
数据访问接口
类库项目和
数据访问
类库项目(其中包含
数据访问接口
项目中接口的实现)

我在
Data Access Interfaces
程序集中有一个
icoinstrage
接口,看起来像这样(
Coin
只是
Data Access Interfaces
程序集中的一个DTO类):

我的问题是:如何在
webforms
项目中使用
CoinSqlServerStorage
类,而不依赖
数据访问
程序集?
我想这样做,用户可以访问
InsertCoin.aspx
页面来定义一个新硬币,并让它将新硬币存储在数据库

当我准备在
页面中创建
InsertCoin.aspx
页面的
CoinSqlServerStorage
类的实例时,出现了我的问题,但是意识到这将创建对
数据访问
程序集的依赖,而不仅仅是依赖于
数据访问接口
程序集


如何继续?

在这种情况下,您可以再创建一个项目,并将其称为
数据访问DI
,该DI将引用
数据访问
数据访问接口
项目。本项目将负责向所有其他项目(需要)提供所需的
数据访问接口实现

但即使在这种情况下,您也会有两个依赖项:
数据访问接口
数据访问DI
——第一个将提供接口,第二个将提供实现

数据访问DI
项目将使您的其他项目与实现隔离,即使您将有多个
数据访问项目,例如:
数据访问Mongo
数据访问Sql
数据访问Raven

如何在web窗体项目中使用CoinSqlServerStorage类而不创建对数据访问程序集的依赖关系

您可以使用支持XML配置的DI容器。这将允许您仅在运行时绑定到数据访问程序集

尽管如此,在大多数情况下,这不是一件好事

我将回顾一下,并说web表单项目可以引用数据访问库

web表单项目是一个特殊的项目,它不仅仅是一个类库。web表单项目本身构成了应用程序,应用程序需要引用它使用的所有其他类库,而不仅仅是包含接口的库

基本上,web表单项目必须包含,并且组合根需要了解所有信息

你可能想看一看(和这个问题),进行相关的讨论

如何在webforms项目中使用CoinSqlServerStorage类而不创建对数据访问程序集的依赖关系

你为什么认为这是个问题?如果你真的这么做了,在解决方案编译完成后,看看你的bin文件夹。可执行文件有很多依赖项

实体与部件引用无关。好。依赖倒置原则可能会改变

迪普说:

A.高级模块不应依赖于低级模块。两者都应该依赖于抽象。
抽象不应该依赖于细节。细节应该取决于抽象

在您的案例中,高级模块(web表单项目)引用低级模块(DAL)。您的底层模块依赖于抽象(dal接口项目)

那很好


然而,我通常会将DAL接口添加到我的业务层项目中,因为正是BL中的需求驱动了DAL接口的设计。

如果我理解正确,可能您的项目结构有点不合理。有多种方法可以实现可靠的友好设置,但我使用以下方法。1) 查看项目2)域项目(定义模型、服务和存储库(ICOInstrage)接口)3)基于源类型(如SQL Server)的每个存储库的项目。然后,视图同时引用域项目和任何已使用的特定存储库。因此,最终你会有类似“Coin.Website”、“Coin.Domain”和“Coin.Repository.SQLServer”的项目。这是一个很好的问题,因为大多数开发人员甚至都没有意识到这个问题,更不用说解决它了。与其直接回答,不如说1)读一下依赖注入。它是一种使SOLID更易于实现的技术/工具。2) 看看MVC。优秀编程的许多方面很难(几乎不可能)用webforms实现。依赖项注入非常重要,它已内置到即将发布的ASP.NET/MVC版本中,webforms即将退出。谢谢@ScottHannen。我计划在SOLID和WCF之后学习MVC,因为这是我目前的工作想要我学习的。现在,我需要在webforms中完成它。DI是我目前正在阅读的SOLID book中的一部分,因此我很期待它。相关:
public interface ICoinStorage
{
    void Persist(IEnumerable<Coin> coins);
}
public class CoinSqlServerStorage : ICoinStorage
{
    private string sqlConnectionString;

    public CoinSqlServerStorage(string connectionStringName)
    {
        sqlConnectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
    }

    public void Persist(IEnumerable<Coin> coins)
    {
        using (var connection = new SqlConnection(sqlConnectionString))
        using (var command = new SqlCommand() { Connection = connection })
        {
            foreach (var coin in coins)
            {
                command.Parameters.AddWithValue("@Name", coin.Name);
                command.Parameters.AddWithValue("@Weight", coin.Weight);
                command.Parameters.AddWithValue("@Thickness", coin.Thickness);
                command.Parameters.AddWithValue("@Value", coin.Value);
                command.Parameters.AddWithValue("@Condition", (int)coin.Condition);

                command.CommandText = "INSERT INTO Coins (Name, Weight, Thickness, Value, ConditionID) " +
                                      "VALUES (@Name, @Weight, @Thickness, @Value, @Condition);";

                command.Connection.Open();
                command.ExecuteNonQuery();
            }
        }
    }
}