Skip to content

Instantly share code, notes, and snippets.

@sakapon
Last active June 22, 2017 08:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sakapon/fac58772e6c6e148d54880c0106e50b3 to your computer and use it in GitHub Desktop.
Save sakapon/fac58772e6c6e148d54880c0106e50b3 to your computer and use it in GitHub Desktop.
ProxySample/TransparentHttpConsole/HttpProxy.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;
namespace TransparentHttpConsole
{
public static class HttpProxy
{
public static IService CreateProxy<IService>()
{
return (IService)new HttpProxy<IService>().GetTransparentProxy();
}
}
public class HttpProxy<IService> : RealProxy
{
public string BaseUri { get; }
public HttpProxy() : base(typeof(IService))
{
var serviceType = typeof(IService);
if (!serviceType.IsInterface) throw new InvalidOperationException("IService must be an interface.");
var baseUriAttribute = serviceType.GetCustomAttribute<BaseUriAttribute>(true);
if (baseUriAttribute == null) throw new InvalidOperationException("IService must have a BaseUriAttribute.");
BaseUri = baseUriAttribute.BaseUri;
}
public override IMessage Invoke(IMessage msg)
{
var methodCall = (IMethodCallMessage)msg;
if (methodCall.MethodBase.DeclaringType == typeof(object))
{
var result =
methodCall.MethodName == "GetType" ? typeof(IService) :
methodCall.MethodBase.Invoke(this, methodCall.InArgs);
return CreateReturnMessage(result, methodCall);
}
var query = Enumerable.Range(0, methodCall.InArgCount)
.ToDictionary(methodCall.GetInArgName, methodCall.GetInArg);
switch (methodCall.MethodName)
{
case "Get":
return CreateReturnMessage(HttpHelper.Get(BaseUri, query), methodCall);
default:
throw new InvalidOperationException($"The method \"{methodCall.MethodName}\" is not available.");
}
}
static IMethodReturnMessage CreateReturnMessage(object returnValue, IMethodCallMessage methodCall)
{
return new ReturnMessage(returnValue, new object[0], 0, methodCall.LogicalCallContext, methodCall);
}
#region Methods of Object class
// GetType method can not be overridden.
public override int GetHashCode() => base.GetHashCode();
public override bool Equals(object obj) => ReferenceEquals(GetTransparentProxy(), obj);
public override string ToString() => typeof(IService).ToString();
#endregion
}
[AttributeUsage(AttributeTargets.Interface, Inherited = false, AllowMultiple = false)]
public sealed class BaseUriAttribute : Attribute
{
public string BaseUri { get; }
public BaseUriAttribute(string baseUri)
{
BaseUri = baseUri;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace TransparentHttpConsole
{
class Program
{
static void Main(string[] args)
{
var cgis = HttpProxy.CreateProxy<ICgisService>();
Console.WriteLine(cgis.Get("6048301"));
Console.WriteLine(cgis.Get("501", 1));
}
}
// http://zip.cgis.biz/
[BaseUri("http://zip.cgis.biz/xml/zip.php")]
public interface ICgisService
{
string Get(string zn);
string Get(string zn, int ver);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment