C#同一解决方案下如何实现类库与其他项目类、窗体的相互访问
跨项目访问权限问题修复
- 首先修正引用配置:
using语句后需跟随类库的命名空间,而非dll文件名,你当前写的using db.dll;是错误写法,替换为db类库中定义的根命名空间即可 - 确认db类库中需要对外暴露的类、方法、属性的访问修饰符为
public:C#类默认访问修饰符为internal,仅允许当前程序集内部访问,外部项目就算添加了引用也无法调用 - 若不想将类型暴露为
public,可在db类库项目的AssemblyInfo.cs文件中添加特性:[assembly: InternalsVisibleTo("你的WinForm项目的程序集名称")],指定的项目即可访问当前类库的internal成员 - 优先添加项目引用而非直接引用dll文件:右键WinForm项目→添加→项目引用,选择同解决方案下的db类库项目,后续类库修改后会自动同步,无需手动更新dll
DataGridView访问错误的根源与修复
你在db.dll中直接操作窗体控件的写法本身不符合分层架构规范:db类库作为底层公共组件,既没有引用System.Windows.Forms程序集,也不可能感知到上层窗体项目中定义的控件实例,自然会抛出找不到控件的错误。
正确的分层写法如下:
- 在db.dll中只封装数据库逻辑,返回数据结果,不涉及任何UI操作:
public class DbOperator { public DataTable GetAllInformation() { using(MySqlConnection con = new MySqlConnection("datasource= localhost; database=sampledb;port=3306; username = root; password= ")) { con.Open(); MySqlDataAdapter adapter = new MySqlDataAdapter("select * from information", con); DataTable dt = new DataTable(); adapter.Fill(dt); return dt; } } }
- 在窗体项目的后台代码中调用db层方法,完成控件绑定:
// 窗体后台代码 DbOperator dbOp = new DbOperator(); DataGridView1.DataSource = dbOp.GetAllInformation();
特别注意:禁止将UI操作逻辑写在数据库操作类库中,会导致层级强耦合,后续需求迭代时维护成本会大幅提升
同解决方案多dll(多项目)通信通用方案
- 常规分层调用:遵循上层依赖下层的规则,业务/UI层依赖公共类库层,直接调用下层暴露的
public方法完成数据读写,这是最常用的通信方式 - 事件/委托回调:如果需要底层类库主动通知上层执行操作(比如数据库异常需要弹窗提示),可在底层类库中定义委托和事件,上层项目订阅对应事件,触发时执行UI、业务逻辑,可避免底层依赖上层
- 接口抽象:如果两个类库需要双向交互,可单独抽离公共接口层作为独立类库,两个项目都引用该接口层,通过接口类型传递实例,避免出现循环引用
- 禁止出现A项目引用B项目、B项目又引用A项目的循环引用场景,编译会直接报错,遇到双向通信需求优先用事件、接口方案解决
内容的提问来源于stack exchange,提问作者Marcell Nemeth
相关产品推荐
相关产品推荐

