如何在 WCF 中使用 DomainModel
How to use DomainModel Into WCF
背景:我需要发布一个简单的项目,它将用于将数据从我的存储传输到其他地方(其他将使用我的WCF的开发人员。WCF将用于传输数据(保护数据库等on)。我在我的项目(基础部分)中使用了洋葱架构。
--------------------------------------
| WCF |
| ---------------------------------- |
| | Interfaces for working with DB | |
| | ------------- | |
| | |DomainModel| | |
| | ------------- | |
| -----------------------------------|
--------------------------------------
我用一个简单的例子来说明我的问题:
我有这样的 DomainModel:
[DataContract]
public class User
{
private string _name;
private List<Text> _texts;
public User(string name, List<Text> texts)
{
_name = name;
_texts = texts;
}
[DataMember]
public string Name { get { return _name; } }
[DataMember]
public List<Text> Texts { get { return _texts; } }
}
[DataContract]
public class Text
{
private string _name;
public Text(string name)
{
_name = name;
}
[DataMember]
public string Name { get { return _name; } }
}
WCF 服务有这个方法:
public DomainModel.User ReturnUser()
{
User user = new User("Texts",
new List<Text>()
{
new Text("TextOne"),
new Text("TextTwo")
});
return user;
}
但是当我调用方法时
static void Main(string[] args)
{
try
{
ServiceRomanClient client = new ServiceRomanClient();
User user = client.ReturnUser();
Console.WriteLine(user.Name);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
我得到这个异常:
这可能是由于服务端点绑定未使用 HTTP 协议。
这也可能是由于 HTTP 请求上下文被服务器中止
(可能是由于服务关闭)。有关详细信息,请参阅服务器日志。
如果我在此更改 DomainModel 中的属性(我添加了设置)
[DataContract]
public class User
{
private string _name;
private List<Text> _texts;
public User(string name, List<Text> texts)
{
_name = name;
_texts = texts;
}
[DataMember]
public string Name { get { return _name; } set{ _name = value; } }
[DataMember]
public List<Text> Texts { get { return _texts; } set { _texts = value; } }
}
[DataContract]
public class Text
{
private string _name;
public Text(string name)
{
_name = name;
}
[DataMember]
public string Name { get { return _name; } set{ _name = value;} }
}
我没有执行,但我违反了 S.O.L.I.D 原则。
我不想将集合添加到 DomainModel 中,我建议解决此问题的更好方法是在 DomainModel 和 WCF 之间创建一个传输层。
如果您能根据您的经验告诉我您的想法,我将不胜感激。
您可以给 属性 一个私有的 setter。这样数据协定序列化器应该仍然能够序列化对象,但您不会将 属性 的 setter 暴露给域模型之外的任何代码。
或者,您可以实现一个数据传输对象,它实际上只是一个 class 和一堆 public getter 和 setter,并将其用作您的 WCF 数据协定。我想这个选项的缺点是您必须编写一些映射代码或使用自动映射工具在您的域模型和数据传输对象之间进行映射。
背景:我需要发布一个简单的项目,它将用于将数据从我的存储传输到其他地方(其他将使用我的WCF的开发人员。WCF将用于传输数据(保护数据库等on)。我在我的项目(基础部分)中使用了洋葱架构。
--------------------------------------
| WCF |
| ---------------------------------- |
| | Interfaces for working with DB | |
| | ------------- | |
| | |DomainModel| | |
| | ------------- | |
| -----------------------------------|
--------------------------------------
我用一个简单的例子来说明我的问题:
我有这样的 DomainModel:
[DataContract]
public class User
{
private string _name;
private List<Text> _texts;
public User(string name, List<Text> texts)
{
_name = name;
_texts = texts;
}
[DataMember]
public string Name { get { return _name; } }
[DataMember]
public List<Text> Texts { get { return _texts; } }
}
[DataContract]
public class Text
{
private string _name;
public Text(string name)
{
_name = name;
}
[DataMember]
public string Name { get { return _name; } }
}
WCF 服务有这个方法:
public DomainModel.User ReturnUser()
{
User user = new User("Texts",
new List<Text>()
{
new Text("TextOne"),
new Text("TextTwo")
});
return user;
}
但是当我调用方法时
static void Main(string[] args)
{
try
{
ServiceRomanClient client = new ServiceRomanClient();
User user = client.ReturnUser();
Console.WriteLine(user.Name);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
我得到这个异常: 这可能是由于服务端点绑定未使用 HTTP 协议。 这也可能是由于 HTTP 请求上下文被服务器中止 (可能是由于服务关闭)。有关详细信息,请参阅服务器日志。
如果我在此更改 DomainModel 中的属性(我添加了设置)
[DataContract]
public class User
{
private string _name;
private List<Text> _texts;
public User(string name, List<Text> texts)
{
_name = name;
_texts = texts;
}
[DataMember]
public string Name { get { return _name; } set{ _name = value; } }
[DataMember]
public List<Text> Texts { get { return _texts; } set { _texts = value; } }
}
[DataContract]
public class Text
{
private string _name;
public Text(string name)
{
_name = name;
}
[DataMember]
public string Name { get { return _name; } set{ _name = value;} }
}
我没有执行,但我违反了 S.O.L.I.D 原则。
我不想将集合添加到 DomainModel 中,我建议解决此问题的更好方法是在 DomainModel 和 WCF 之间创建一个传输层。
如果您能根据您的经验告诉我您的想法,我将不胜感激。
您可以给 属性 一个私有的 setter。这样数据协定序列化器应该仍然能够序列化对象,但您不会将 属性 的 setter 暴露给域模型之外的任何代码。
或者,您可以实现一个数据传输对象,它实际上只是一个 class 和一堆 public getter 和 setter,并将其用作您的 WCF 数据协定。我想这个选项的缺点是您必须编写一些映射代码或使用自动映射工具在您的域模型和数据传输对象之间进行映射。