Я пытаюсь создать своего рода связь WCF между двумя программами (чтобы бросить вызов себе).
То, что я имею в виду под WCF, - это возможность иметь интерфейс в качестве контракта в общей библиотеке.Затем возможность использовать этот контракт в моих двух программах.Я хотел бы использовать их, как мы это делаем в WCf, это означает, что клиент вызывает простой метод из того же программного обеспечения, но на самом деле использует TcpClient, вызывающий TcpServer с другой стороны ....
Как WCF, я хотел бы быть универсальным, поэтому я не хочу готовый класс, который оборачивает мою сетевую логику для конкретного контракта.Как WCF, я хотел бы иметь возможность написать интерфейс контракта, затем создать новый экземпляр класса say «ClientBase» с моим контрактом в качестве параметров шаблона, а затем использовать этот клиент в качестве «Удаленного» моего другого программного обеспечения.
В качестве примера всегда лучше вот что я хотел бы:
В совместном проекте:
public interface IFooContract
{
void Add(int a, int b);
}
В клиенте:
class Program
{
static void Main(string[] args)
{
using (var client = new ClientFooContract())
{
var result = client.Add(5, 2);
}
}
}
class ClientFooContract : MyClientBase<IFooContract>, IFooContract, IDisposable
{
public int Add(int a, int b)
{
return Channel.Add(a, b);
}
}
class MyClientBase<T> where T : class
{
protected T Channel;
public MyClientBase()
{
Channel = /*Create Channel instance*/
}
}
Моя реализация действительно близка к основам WCF, но моя проблема заключается в создании экземпляра канала, потому что, конечно, у меня нет ни одного класса, который я мог бы создать.Мне нужен своего рода динамический класс, который реализует этот конкретный контракт и для каждого метода этого контракта обрабатывает сетевую логику для создания TcpClient, подключения его к удаленному серверу, отправки данных, ожидания ответа и возврата результата в ClientFooContract.
Конечно, я мог бы создать класс ChannelBase, который бы реализовывал контракт и управлял сетью для каждого из этих методов, но я хотел бы быть универсальным как WCF, чтобы иметь возможность предоставлять любой тип контракта для моей системы.
В настоящее время я работаю с пространством имен Emit, пытаясь создать динамический класс, который на данный момент содержит метод, вот мой незаконченный код для создания метода:
class Program
{
static void Main(string[] args)
{
var methods = new List<Method>();
methods.Add(new Method()
{
Name = "Add",
Params = new List<MethodParam>()
{
new MethodParam()
{
Name = "a",
Type = typeof(int)
},
new MethodParam()
{
Name = "b",
Type = typeof(int)
}
},
ReturnType = typeof(int)
});
MyTypeBuilder.CompileResultType(methods);
}
}
public class Method
{
public string Name;
public List<MethodParam> Params;
public Type ReturnType;
}
public class MethodParam
{
public string Name;
public Type Type;
}
public static class MyTypeBuilder
{
public static Type CompileResultType(List<Method> methodList)
{
TypeBuilder tb = GetTypeBuilder();
ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
if (methodList != null)
foreach (var method in methodList)
CreateMethod(tb, method);
Type objectType = tb.CreateType();
return objectType;
}
private static TypeBuilder GetTypeBuilder()
{
var typeSignature = "MyDynamicType";
var an = new AssemblyName(typeSignature);
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
//AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
TypeBuilder tb = moduleBuilder.DefineType(typeSignature,
TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout,
null,
new Type[] { typeof(IFoo) });
return tb;
}
private static void CreateMethod(TypeBuilder tb, Method method)
{
MethodBuilder methodBuilder = tb.DefineMethod(method.Name, MethodAttributes.Public, method.ReturnType, method.Params.Select(l => l.Type).ToArray());
ILGenerator il = methodBuilder.GetILGenerator();
}
}
Вот моя борьба, яне знаю, как добавить тело к моему динамическому методу, я нашел в интернете несколько примеров того, как создать локальную переменную и т. д., но на самом деле, как я могу создать TcpClient с IL, мне нужно поместить все это в отдельный методтогда вызвать этот метод?и как ?Как на самом деле я могу сделать простой вызов console.writeLine для фактического тестирования моей системы?
Моя проблема на самом деле заключается в создании MethodBody, потому что здесь мне придется проделать большую работу, а не просто объявить локальныйпеременная и обрабатывать основные операции.Если есть хотя бы способ вызвать другой метод в другом классе, это будет полезно
Если вы что-нибудь знаете, спасибо за вашу помощь