C# 将业务层类更改为松散耦合
我有下面的代码,我正在工作。我正在研究adon.net层的数据访问。我的业务层类C# 将业务层类更改为松散耦合,c#,C#,我有下面的代码,我正在工作。我正在研究adon.net层的数据访问。我的业务层类UserBAL有问题。问题是我正在UserBAL的构造函数中创建dal和dbmanager的实例。对于UserBAL,如何将其更改为松散耦合?希望你明白我的意思 public interface IEntity { int Id { get; set; } int DoSomething(string one, int two); } public class User : IEntity {
UserBAL
有问题。问题是我正在UserBAL
的构造函数中创建dal和dbmanager的实例。对于UserBAL
,如何将其更改为松散耦合?希望你明白我的意思
public interface IEntity
{
int Id { get; set; }
int DoSomething(string one, int two);
}
public class User : IEntity
{
public int Id { get; set; }
public int DoSomething(string one, int two)
{
throw new NotImplementedException();
}
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
public class UserBal //busines logic
{
private readonly IRepositoryDal<User> _userRepositoryDal;
public UserBal()
{
_userRepositoryDal = new UserRepositoryDal(new DbManager("sqlserver?"));
}
public IEnumerable<User> SearchByName(string name)
{
return _userRepositoryDal.SearchByName(name);
}
}
interface IRepositoryDal<T> where T : IEntity
{
IEnumerable<T> SearchByName(string username);
T SearchById(string id);
void Update(T entity);
void Remove(T entity);
void Add(T entity);
}
public class UserRepositoryDal: IRepositoryDal<User>
{
private readonly IDbManager _dbManager;
public UserRepositoryDal(IDbManager dbManager)
{
//read from either singleton or configuration file !!
_dbManager = dbManager;
}
public IEnumerable<User> SearchByName(string username)
{
var parameters = new List<IDbDataParameter>
{
_dbManager.CreateParameter("@FirstName", 50, username, DbType.String),
};
var userDataTable = _dbManager.GetDataTable("storedpr2",
CommandType.StoredProcedure, parameters.ToArray());
foreach (DataRow dr in userDataTable.Rows)
{
var user = new User
{
Id = int.Parse(dr["Id"].ToString()),
Firstname = dr["Firstname"].ToString(),
Lastname = dr["LastName"].ToString(),
Email = dr["Email"].ToString()
};
yield return user;
}
}
public User SearchById(string id)
{
var parameters = new List<IDbDataParameter>
{
_dbManager.CreateParameter("@Id", 50, id, DbType.Int32),
};
var userDataTable = _dbManager.GetDataTable("storedpr2",
CommandType.StoredProcedure, parameters.ToArray());
return new User
{
Id = int.Parse(userDataTable.Rows[0]["Id"].ToString()),
Firstname = userDataTable.Rows[0]["Firstname"].ToString(),
Lastname = userDataTable.Rows[0]["LastName"].ToString(),
Email = userDataTable.Rows[0]["Email"].ToString()
};
}
public void Update(User entity)
{
throw new System.NotImplementedException();
}
public void Remove(User entity)
{
throw new System.NotImplementedException();
}
public void Add(User entity)
{
throw new System.NotImplementedException();
}
}
public partial class FrmLogin : Form
{
private readonly UserBal _userBal;
public FrmLogin()
{
InitializeComponent();
_userBal = new UserBal();
}
}
公共接口的可扩展性
{
int Id{get;set;}
int DoSomething(字符串一,int二);
}
公共类用户:IEntity
{
公共int Id{get;set;}
公共整数DoSomething(字符串一,整数二)
{
抛出新的NotImplementedException();
}
公共字符串名{get;set;}
公共字符串Lastname{get;set;}
公共字符串电子邮件{get;set;}
公共字符串密码{get;set;}
}
公共类UserBal//业务逻辑
{
私有只读IRepositoryDal _userRepositoryDal;
公共用户bal()
{
_userRepositoryDal=newuserrepositorydal(newdbmanager(“sqlserver?”));
}
公共IEnumerable SearchByName(字符串名称)
{
返回_userRepositoryDal.SearchByName(名称);
}
}
接口IRepositoryDal,其中T:Entity
{
IEnumerable SearchByName(字符串用户名);
T SearchById(字符串id);
无效更新(T实体);
无效删除(T实体);
无效添加(T实体);
}
公共类UserRepositoryDal:IRepositoryDal
{
专用只读IDbManager _dbManager;
公共用户RepositoryDal(IDbManager dbManager)
{
//从单例或配置文件读取!!
_dbManager=dbManager;
}
公共IEnumerable SearchByName(字符串用户名)
{
var参数=新列表
{
_dbManager.CreateParameter(“@FirstName”,50,用户名,DbType.String),
};
var userDataTable=_dbManager.GetDataTable(“storedpr2”,
CommandType.StoredProcess,parameters.ToArray());
foreach(userDataTable.Rows中的DataRow dr)
{
var user=新用户
{
Id=int.Parse(dr[“Id”].ToString()),
Firstname=dr[“Firstname”].ToString(),
Lastname=dr[“Lastname”].ToString(),
Email=dr[“Email”].ToString()
};
用户收益率;
}
}
公共用户SearchById(字符串id)
{
var参数=新列表
{
_dbManager.CreateParameter(“@Id”,50,Id,DbType.Int32),
};
var userDataTable=_dbManager.GetDataTable(“storedpr2”,
CommandType.StoredProcess,parameters.ToArray());
返回新用户
{
Id=int.Parse(userDataTable.Rows[0][“Id”].ToString()),
Firstname=userDataTable.Rows[0][“Firstname”].ToString(),
Lastname=userDataTable.Rows[0][“Lastname”].ToString(),
Email=userDataTable.Rows[0][“Email”].ToString()
};
}
公共无效更新(用户实体)
{
抛出新系统。NotImplementedException();
}
公共作废删除(用户实体)
{
抛出新系统。NotImplementedException();
}
公共作废添加(用户实体)
{
抛出新系统。NotImplementedException();
}
}
公共部分类FrmLogin:表单
{
私有只读UserBal\u UserBal;
公共FrmLogin()
{
初始化组件();
_userBal=新的userBal();
}
}
您应该使用,对于所需的依赖项,您可以使用构造函数注入,例如:
public class UserBal
{
private readonly IRepositoryDal<User> _userRepositoryDal;
public UserBal(IRepositoryDal<User> userRepositoryDal)
{
_userRepositoryDal = userRepositoryDal
?? throw new ArgumentNullException(nameof(userRepositoryDal));
}
...
}
公共类UserBal
{
私有只读IRepositoryDal _userRepositoryDal;
public UserBal(IRepositoryDal userRepositoryDal)
{
_userRepositoryDal=userRepositoryDal
?抛出新ArgumentNullException(nameof(userRepositoryDal));
}
...
}
依赖项注入是一条出路。下面是一个简单的例子
考虑到你的课程可能是这样的:
public interface IEntity { }
public interface IRepositoryDal<T> where T : IEntity { }
public interface IDbManager { }
public class User : IEntity { }
public class UserBal //busines logic
{
[Injectivity.Attributes.Inject]
private IRepositoryDal<User> _userRepositoryDal;
}
public class UserRepositoryDal: IRepositoryDal<User>
{
[Injectivity.Attributes.Inject]
private IDbManager _dbManager;
}
public class DbManager : IDbManager
{
[Injectivity.Attributes.Construct()]
public DbManager([Injectivity.Attributes.Key("dbKey", typeof(string))] string x)
{
Console.WriteLine($"DbManager created with parameter \"{x}\"");
}
}
context.SetDecorator<IRepositoryDal<User>, UserRepositoryDalDecorator>();
这将导致对
context.Resolve()
或[Inject]
属性的所有调用自动将实际实例包装在此装饰器中。非常适合拦截用于调试目的的方法调用。您在此处寻找依赖项注入。在构造UserBal
时,您会传递一个实例,即newuserbal(newuserrepositorydal(new DbManager(“sqlserver”))您也可以考虑使用IOC容器来管理这些依赖项,例如Autofac - .jimyjimm,然后您必须设置AutoFac并将其与您的APP集成。不确定,但问题是:“新UserBal(新UserRepositoryDal(新DbMeCerver(SQLServer?))”因为我首先从表示层传递新的UserRepositoryDal。表示层不应该不知道这个对象吗?DbManager也从表示层传递。据我所知,从那一点开始,应该只知道UserBal。你继续这个模式,所以表示层注入了一个UserBal
,因此不需要知道它是如何构造的。所有连接都发生在应用程序的组成根中。我建议您阅读.NET中的依赖项注入。@devdigital您能解释一下吗?我仍然需要从表示层这样称呼它吗?:new UserBal(new UserRepositoryDal)(new DbManager(“sqlserver?”)是否可以在没有属性的情况下更改它?例如IoC容器?@JimmyJimm-这是一个IoC容器的示例。它只是碰巧使用属性来简化注册。我确实将其设置为允许通过代码注册(如我的问题中所示)。这只关系到类的注册需要如何工作。属性使您可以轻松注册整个程序集,从而在运行时交换程序集。
DbManager created with parameter "sqlserver?"
context.SetDecorator<IRepositoryDal<User>, UserRepositoryDalDecorator>();