我熟悉标准存储库,其界面类似于:
public interface IRepository<T>
{
IEnumerable<T> All();
T GetByID(int id);
//etc...
}
我的问题涉及尝试在Silverlight中实现此模式,这限制了对异步调用的远程数据访问(这有效地从接口的方法中删除了返回值的概念)如何创建IAsyncRepository
以及如何会在返回的调用后发生数据绑定到控件的ItemSource吗?
答案 0 :(得分:3)
如果要在Silverlight中使用存储库模式,我认为最好的方法是将某种回调方法传递给每个方法,然后在异步调用完成时由存储库调用。您可以在回调函数中传递返回的对象,这时您可以设置数据绑定。
下面的代码是一个如何工作的示例。它没有使用标准存储库模式,但我认为您可以看到如何对其进行适当修改:
public void CreatedNamedRoom(string ownerUserId, string roomName, Action<Exception, Room> callback)
{
notificationClient.CreateNamedRoomAsync(ownerUserId, roomName, callback));
}
void notificationClient_CreateNamedRoomCompleted(object sender, CreateNamedRoomCompletedEventArgs e)
{
var callback = e.UserState as Action<Exception, Room>;
if (callback != null)
{
callback(e.Error, e.Result);
}
}
然后你使用这样的东西:
roomData.CreatedNamedRoom(userId, roomName, (error1, room) =>
{
if (error1 == null)
{
// Setup your databinding here...
this.Room = room;
}
});
实际上,存储库成为MS使您使用的恼人的事件驱动的异步WCF代理方法的包装器。我通常发现回调比事件更容易使用,因为你并不总是知道是什么触发了事件,并且适当地保持状态是PITA。但是如果你用一个可以用回调的图层包装事件(上面的Action&lt;&gt;位),维护适当的状态就容易多了。
我还应该注意,泛型存储库可能不适用于Silverlight,假设你在后端使用类似WCF的东西,因为SOAP等人不能很好地支持泛型。更好的方法是将存储库用作基础架构合同,如here所述。它在架构上更好,并且使用Silverlight / WCF可以更好地工作。