目前我的UI代码依赖于业务逻辑(二进制dll)接口,其中实例是使用unity容器注入的。
未来计划是,业务逻辑可以作为具有相同接口的WCF服务托管。由于客户端代码依赖于接口,因此不应进行任何更改。应该从WCF注入实例。以下方法是正确的做法,还是有任何最佳做法?
public interface MyServiceContract
{
string GetData(int value);
}
public class Service1 : MyServiceContract
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
public class ServiceFactory
{
//Get instance from WCF
public T GetWCFService<T>()
{
ChannelFactory<T> factory = null;
var binding = new BasicHttpBinding();
var address = new EndpointAddress("uri");
factory = new ChannelFactory<T>(binding, address);
var channel = factory.CreateChannel();
return channel;
}
//Get instance from Binary Reference
public T GetService<T>()
{
return UnityContainer.Resolve<T>();
}
}
public class Test
{
//calls binary reference method
private void Test()
{
var mysvc = new ServiceFactory().GetService<MyServiceContract>();
var resturnmessage = mysvc.GetData(9);
Console.WriteLine(resturnmessage);
}
//calls wcf method
private void Test2()
{
var mysvc = new ServiceFactory().GetWCFService<MyServiceContract>();
var resturnmessage = mysvc.GetData(9);
Console.WriteLine(resturnmessage);
}
}
答案 0 :(得分:1)
这种方法将工作,但并不完美。你永远不会关闭你的联系。您需要一个符合您的界面的代理类,以便您可以注入它。该类可以拥有接口的通道并通过所有调用。但它还需要确保在需要关闭时关闭此通道。
如果您有服务工厂(不是个人粉丝),您应该有一个具有单一方法IBusinessLogicFactory
的界面public T GetService<T>()
。然后,您可以从此接口派生UnityInjectorFactory和WCFServiceFactory。如果您的代码知道它得到了什么,因为您需要调用不同的方法,那么您的抽象就会被破坏。
您的测试用例应如下所示:
public class Test
{
private void RunTests()
{
Test(new WcfFactory());
Test(new UnityContainerFactory());
}
private void Test(IMyServiceFactory factory)
{
var mysvc = factory.GetService<MyServiceContract>();
var returnmessage = mysvc.GetData(9);
Console.WriteLine(returnmessage);
}
}
关闭渠道比以前更加复杂。它被认为是一个错误,但微软表示,现在人们依赖这种行为,他们无法修复它。无论如何:
关闭任何CommunicationObject:
public static void DisposeCommunicationObject(ICommunicationObject communicationObject)
{
if (communicationObject != null)
{
try
{
communicationObject.Close();
}
catch
{
communicationObject.Abort();
}
finally
{
((IDisposable)communicationObject).Dispose();
}
}
}
您作为频道获得的内容可以转换为IClientChannel,然后传递给此函数。如果您的计划适合,您需要自己找出答案。如果您不想再进行沟通,可能在发生故障之后再进行沟通。