如何将查找路径的定义从客户端移动到服务器端?

时间:2017-07-24 11:41:24

标签: c# .net wcf

我有一个WCF服务,我已经编写了接受调用者传递给它的对象,这些服务已经用告诉服务如何查找字符串表示的属性进行了修饰。例如,该服务可以将CAR_ID 1转换为"丰田",CAR_ID 2转换为"本田"等等。

那部分效果很好。我遇到一些重大问题的地方是我加载类型的想法,因此WCF可以处理序列化和反序列化而不会丢失对象属性的关键属性。我的目标是在远程共享上放置一个文件夹,组织中的人员可以放弃他们装饰的.dll,然后调用传递在已删除的.dll中定义的对象的服务。在大多数情况下,这是很好的,除了一件事:我有随机问题锁定放在.dll上,所以我无法在遥控器上更新它们份额。

我希望将路径定义移动到指向安装服务的本地文件夹,或者能够自定义服务器端。就目前的情况而言,我必须发布用于在我的界面中提取已知类型的代码,这意味着我输入的任何路径都是从调用者的角度评估的,不是我喜欢的服务。有没有办法摆脱这种困境?

以下是我的合同副本。

[ServiceKnownType("RegisterKnownTypes", typeof(MyStringTypeHelper))]
[ServiceContract]
public interface IMyStringParser
{
   [OperationContract]
   string GetStringRepresentation(object target);

   [OperationContract]
   string GetStringRepresentationWithComparison(object sourceTarget, object destinationTarget, bool useHtmlMarkup);
}

internal static class MyStringTypeHelper
{
   public static IEnumerable<Type> RegisterKnownTypes(ICustomAttributeProvider provider)
   {
      var files = Directory.GetFiles(@"\\path\to\remote\dlls"); // how can I move the definition of this path to be server side, not client side?

      if (files.Length == 0)
         return new List<Type>();

      var result = new List<Type>();
      foreach (var file in files)
      {
         result.AddRange(Assembly.LoadFile(Path.GetFullPath(file)).GetExportedTypes());
      }

      return result;
   }
}

1 个答案:

答案 0 :(得分:0)

您可以使用DataContractResolver

public class SharedTypeResolver : DataContractResolver
{
    public override bool TryResolveType(Type dataContractType, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace)
    {
        if (!knownTypeResolver.TryResolveType(dataContractType, declaredType, null, out typeName, out typeNamespace))
        {
            XmlDictionary dictionary = new XmlDictionary();
            typeName = dictionary.Add(dataContractType.FullName);
            typeNamespace = dictionary.Add(dataContractType.Assembly.FullName);
        }
    }

    public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver)
    {
        return knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, null) ?? Type.GetType(typeName + ", " + typeNamespace);
    }
}

解析器接受您在服务中使用的每种类型。但您必须将解析程序添加到客户端端点和服务器端点。像这样:

Host = new ServiceHost(typeof(MyService));

ContractDescription cd = Host.Description.Endpoints[0].Contract;
foreach (var operation in cd.Operations)
{
    operation.Behaviors.Find<DataContractSerializerOperationBehavior>()
                .DataContractResolver = new SharedTypeResolver();
}