gpt4 book ai didi

c# - C# 和 Visual Studio 2005 程序集之间的循环引用

转载 作者:太空狗 更新时间:2023-10-30 00:47:20 24 4
gpt4 key购买 nike

我正在努力标准化我所有应用程序的分层/n 层设计的一种单一方式。

我正在尝试将我所有的应用程序分为 5 层。

代码:


|界面 |

|

|业务对象 |

|

|或映射器 |

|

|数据访问 |

|

|关系型数据库 |

假设我正在开发一个具有用户登录/注销功能的应用程序。我正在 VS2005 解决方案下创建 4 个项目。每个项目都针对上 4 层之一。我正在按如下方式设计我的业务对象类:-

public class User
{
private string _username;
public string Username
{
get { return _username; }
set { _username = value; }
}

private string _password;
public string Password
{
get { return _password; }
set { _password = value; }
}

public User()
{
}

public bool LogIn(String username, String password)
{
bool success = false;

if (UserMapper.UsernameExists(username))
{
success = UserMapper.UsernamePasswordExists(username, password);
}
else
{
//do nothing
}

return success;
}

public bool LogOut()
{
bool success;
//----some logic
return success;
}

public static User GetUserByUsername(string username)
{
return UserMapper.GetUserByUsername(username);
}

public static UserCollection GetByUserTypeCode(string code)
{
return UserMapper.GetByUserTypeCode(code);
}
}

这就是我为我的对象提供一些与真实场景相匹配的功能的方式。这里的 GetByUsername() 和 GetByUserTypeCode() 是 getter 函数。这些功能与现实世界的逻辑不匹配。因为,在现实世界中,用户永远不会“通过用户名获取”或“通过 UserTypeCode 获取”。所以这些函数保持静态。

我的 O-R Mapper 层类如下:-

public static class UserMapper
{
public static bool UsernameExists(String username)
{
bool exists = false;

if (UserDA.CountUsername(username) == 1)
{
exists = true;
}

return exists;
}

public static bool UsernamePasswordExists(String username, String password)
{
bool exists = false;

if (UserDA.CountUsernameAndPassword(username, password) == 1)
{
exists = true;
}

return exists;
}
}

最后,DA类如下:-

public static class UserDA
{
public static int CountUsername(string username)
{
int count = -1;

SqlConnection conn = DBConn.Connection;

if (conn != null)
{
try
{
SqlCommand command = new SqlCommand();
command.Connection = conn;
command.CommandText = @"SELECT COUNT(*)
FROM User
WHERE User_name = @User_name";
command.Parameters.AddWithValue("@User_name", username);

command.Connection.Open();
object idRaw = command.ExecuteScalar();
command.Connection.Close();

if (idRaw == DBNull.Value)
{
count = 0;
}
else
{
count = (int)idRaw;
}
}
catch (Exception ex)
{
count = -1;
}
}

return count;
}

public static int CountUsernameAndPassword(string username, string password)
{
int count = 0;

SqlConnection conn = DBConn.Connection;

if (conn != null)
{
try
{
SqlCommand command = new SqlCommand();
command.Connection = conn;
command.CommandText = @"SELECT COUNT(*)
FROM User
WHERE User_name = @User_name AND Pass_word = @Pass_word";
command.Parameters.AddWithValue("@User_name", username);
command.Parameters.AddWithValue("@Pass_word", password);

command.Connection.Open();
object idRaw = command.ExecuteScalar();
command.Connection.Close();

if (idRaw == DBNull.Value)
{
count = 0;
}
else
{
count = (int)idRaw;
}
}
catch (Exception ex)
{
count = 0;
}
}

return count;
}

public static int InsertUser(params object[] objects)
{
int count = -1;

SqlConnection conn = DBConn.Connection;

if (conn != null)
{
try
{
SqlCommand command = new SqlCommand();
command.Connection = conn;
command.CommandText = @"INSERT INTO User(ID, User_name, Pass_word, RegDate, UserTypeCode, ActualCodeOrRoll)
VALUES(@ID, @User_name, @Pass_word, @RegDate, @UserTypeCode, @ActualCodeOrRoll)";
command.Parameters.AddWithValue("@ID", objects[0]);
command.Parameters.AddWithValue("@User_name", objects[1]);
command.Parameters.AddWithValue("@Pass_word", objects[2]);
command.Parameters.AddWithValue("@RegDate", objects[3]);
command.Parameters.AddWithValue("@UserTypeCode", objects[4]);
command.Parameters.AddWithValue("@ActualCodeOrRoll", objects[5]);

command.Connection.Open();
count = command.ExecuteNonQuery();
command.Connection.Close();
}
catch (Exception ex)
{
count = -1;
}
}

return count;
}

public static SqlDataReader GetUserByUsername(string username)
{
SqlDataReader dataReader = null;

SqlConnection conn = DBConn.Connection;

if (conn != null)
{
try
{
SqlCommand command = new SqlCommand();
command.Connection = conn;
command.CommandText = @"SELECT * FROM User WHERE User_name = @User_name";
command.Parameters.AddWithValue("@User_name", username);

command.Connection.Open();

dataReader = command.ExecuteReader(CommandBehavior.CloseConnection);

}
catch (Exception ex)
{
dataReader.Close();
dataReader.Dispose();
}
}

return dataReader;
}

public static SqlDataReader GetUserByUserTypeCode(string userTypeCode)
{
SqlDataReader dataReader = null;

SqlConnection conn = DBConn.Connection;

if (conn != null)
{
try
{
SqlCommand command = new SqlCommand();
command.Connection = conn;
command.CommandText = @"SELECT * FROM User WHERE UserTypeCode = @UserTypeCode";
command.Parameters.AddWithValue("@UserTypeCode", userTypeCode);

command.Connection.Open();

dataReader = command.ExecuteReader(CommandBehavior.CloseConnection);

}
catch (Exception ex)
{
dataReader.Close();
dataReader.Dispose();
}
}

return dataReader;
}
}

如果仔细研究这些类,他就会明白,O-R Mapper 层需要 BusinessObject 层的引用。 BusinessObject-层还需要引用O-R Mapper-层。

这应该会产生循环依赖。

如何避免这个问题?

有人建议使用纯数据传输对象 (DTO)。但是,据我所知,根据 OOP,真实世界对象的属性和功能应该作为一个类组合在一起。如果我使用 DTO 那么如何将功能封装到一个类中?此外,我正在创建另一个没有任何属性(BO)的类。对我来说,这在两个方面都违反了 OOP。如果我这样做,那么 OOP 在这个世界上有什么用?同样的答案也适用于“UserManager”类。

我找到了一个 blog .

它讨论了实现接口(interface)。定义一个单独的接口(interface),在 BusinessObject 的数据类中实现它,并针对 BusinessObject 和 OR-Mapper 层中的接口(interface)进行编程。

但我做不到。

任何人都可以通过实际示例向我展示吗?

最佳答案

我认为您可以一起做一些事情来帮助您进行设计。我还认为您可能想阅读 Dependency Injection可能会为您想要做的事情提供更好的设计模式。

假设您只想让现有的工作正常进行:

  • 首先,从 User 类中删除 static 方法,因为它们“创建”用户,因此最好只留在 UserMapper .

  • 在那之后,仍然会有许多方法可能使用 User 类中的 UserMapper 功能。创建一个支持 UserNameExistsUserNamePasswordExists 方法的接口(interface) IUserLookup (或其他东西);将此接口(interface)与 User 类放在同一个项目中。

  • UserMapper 类上实现 IUserLookup,然后将其“注入(inject)”到它创建的 User 类实例中通过构造函数的静态方法,所以基本上,当 UserMapper 创建 User 对象时,它为它们提供了对它自己实现的 IUserLookup 接口(interface)的引用.

这样,User 只使用IUserLookup 上的方法,它们在同一个解决方案中,因此不需要引用。而 UserMapper 引用了这个解决方案,因此它可以创建 User 对象并实现 IUserLookup 接口(interface)。

关于c# - C# 和 Visual Studio 2005 程序集之间的循环引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/924382/

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