我正在使用网络表单,C#,Asp.net。 众所周知,在这个模型中,UI和业务逻辑经常混合在一起。如何有效地分离这些?
我想使用的例子是: 我有一个GridView和一个DataTable(GridView绑定到DataTable,DataTable来自存储过程)。
我希望将GridView(UI)和DataTable(业务逻辑)分离。
为DataTable编写包装器是否值得?是否有经过验证和测试的实用模式,您可以建议遵循这些模式?
如果有经验的人可以发光,那就太棒了。 而且,作为最后一点,我想说ASP MVC现在不是一个选项,所以不推荐它。
我的数据库访问层返回一个DataTable。 请注意,我必须使用此数据库层,因为这是公司政策。
答案 0 :(得分:2)
我最近经历过这个问题,同时从我们的UI层解耦了很多相同的东西。
在我看来,DataTable
不代表业务逻辑。具体来说,它的数据直接从数据库中提取。业务逻辑将数据转换为真正有用的业务对象。
然后,第一步是将DataTable与Business对象分离。
您可以通过创建构成DataTables的DataTables和Collections的对象和List<object>
,然后创建一个显示这些对象的ListView。我在上面发布的链接中介绍了后面的步骤。前面的步骤就像下面这样简单:
List<T>
); 这样,ListView或Gridview就不会与您检索数据的方法紧密耦合。如果您决定稍后从JSON查询或XML文件获取数据会发生什么?然后你必须把它建在那里。
有多种方法可以从数据库中获取数据,我无法在这里查看所有数据。我假设您已经知道如何从数据库中检索数据,如果不这样做,则需要quite a few links。让我们假装您已连接到数据库,并使用SQLDataReader
来检索数据。我们会去那里。
Foo
----
id
Name
Description
这是方法:
private void FillDefault(SqlDataReader reader, Foos foo)
{
try
{
foo.id = Convert.ToInt32(reader[Foo.Properties.ID]);
foo.Name = reader[Foo.Properties.NAME].ToString();
if (!string.IsNullOrEmpty(
reader[Foo.Properties.DESCRIPTION].ToString()))
foo.Description =
reader[Foo.Properties.DESCRIPTION].ToString();
else foo.Description = string.Empty;
}
catch (Exception ex)
{
throw new Exception(
string.Format("Invalid Query.
Column '{0}' does not exist in SqlDataReader.",
ex.Message));
}
}
一旦发生这种情况,您可以在针对while
函数的SQLDataReader.Read()
循环中完成该过程,从而返回一个列表。
一旦你这样做,让我们假装你返回的Foo
是一个列表。如果您这样做,并按照我上面给出的第一个链接,您可以将Dictionary<TKey, TValue>
替换为List<T>
并获得相同的结果(略有不同)。 Properties
类只包含数据库中的列名,因此您可以在一个地方更改它们(如果您想知道的话)。
您始终可以插入中间对象。在这个例子中,我在DataTable和UI之间插入了一个Business Layer,我已经讨论了我上面要做的事情。但是DataTable不是业务对象;它是数据库的直观表示。您无法将其传输到UI层并将其称为解耦。他们说你必须使用DataTable,他们是否说有将DataTable传输到UI?我无法想象他们会这样。如果你这样做,那么你永远不会被解耦。在DataTable和UI层之间总是需要一个中间对象。
答案 1 :(得分:0)
我首先将数据表解耦到垃圾桶。构建一个域层,然后构建一个处理数据库的数据访问层(建议使用ORM)。
然后构建一个服务层,为UI提供数据。所有业务逻辑都应该在服务或实体内部。
答案 2 :(得分:0)
考虑实施MVP(模型视图展示器)模式。它通过演示者界面为您提供商业逻辑的分离,这也允许更好的单元测试功能。然后,aspx页面的代码隐藏只是事件的连接器和属性的getter / setter。您可以在MS模式和实践企业应用程序块中找到它(CAB - 复合应用程序块 - 如果我没有误会)。
您可以在此处详细了解:http://msdn.microsoft.com/en-us/magazine/cc188690.aspx
但是从DataTable / DataSets到对象(POCO)也是首选。