我有一个应用程序,存在于3个不同的表示层... web,移动(离线)和桌面(离线)。核心业务对象对于所有三个都是相同的,并且它们共享相同的验证和业务规则。但是,它们都使用不同的数据库(Web - SQL Server 2008,移动/桌面 - SQL Compact)。通过同步过程,桌面和移动应用程序从服务器的SQL 2008 db中推送和接收数据。
我正在努力想出最好的n级方法而且我有点卡住了。我为业务对象创建了一个程序集,它封装了所有业务规则。我非常希望这个程序集中的每个对象都有一个Save()方法。但是,我不希望此层知道任何特定的数据层。基本上,我希望所有三个表示层都填充这些对象并调用Save()方法。但我希望Save()方法的实现因调用应用程序而异。
我最初创建了一个名为IDataAdapter的接口,然后在IDataAdapter的每个对象上创建了一个静态属性。然后Save()方法刚检查是否已设置,然后将业务对象传递给它的Save()方法。
public interface IDataAdapter
{
void Save(BusinessProxy proxy);
}
public class BusinessProxy
{
public IDataAdapter myAdapter { get; set; }
public bool Save()
{
if (myAdapter == null)
throw new Exception();
myAdapter.Save(this);
}
}
当然,这并不理想,因为表示层需要引用数据层才能设置Adapter属性。我真的很想有一些插件系统,我可以根据应用程序平台换掉data.dll。
有没有人对如何更好地实现这一点有任何建议?
答案 0 :(得分:1)
如果你的意思是“最好的n层方法” 不同的层不应该彼此了解 并且只有一种方法将各部分链接在一起 您可以创建一个全局DataAdapter注册表 基于字典
BusinessProxy可以要求使用其IDataAdapter。
public interface IDataAdapter { void Save(BusinessProxy proxy); } public class BusinessProxy { public static DataAdapterRegistry Adapter = new DataAdapterRegistry(); public bool Save() { Adapter.Save(this); return true; } } public class DataAdapterRegistry : IDataAdapter { private Dictionary<Type, IDataAdapter> registry = new Dictionary<Type, IDataAdapter>(); public void Register(Type type, IDataAdapter adapter) { registry[type] = adapter; } public void Save(BusinessProxy proxy) { IDataAdapter adapter; if (registry.TryGetValue(proxy.GetType(), out adapter)) adapter.Save(proxy); else throw new NotSupportedException(proxy.GetType().FullName); } } class Customer : BusinessProxy { } class Order : BusinessProxy { } class Program { static void Main(string[] args) { BusinessProxy.Adapter.Register(typeof(Customer), new CustomerAdapter()); BusinessProxy.Adapter.Register(typeof(Order), new OrderAdapter()); } }
你可以使用像spring.net这样的“反转控制容器”框架,用xml-configurtaion文件实现硬编码 - 编译时初始化。
答案 1 :(得分:0)
我是Simple的粉丝。
您可以做的一件事就是将Save方法与平台相关的程序集分开。只需将其设为扩展方法,以便最终用户看起来像IDataAdapter的一部分。简单,干净。
答案 2 :(得分:0)
您可以使用IoC(例如structuremap)在表示层中注册IDataAdapter的特定实现。
另一种方法可能是MEF,因此您可以随时交换程序集。