Я привык создавать консольное приложение .Net Framework и предоставлять Add(int x, int y)
функцию через службу WCF с нуля с помощью библиотеки классов (.Net Framework). Затем я использую консольное приложение для прокси-вызова этой функции на сервере.
Однако, если я использую консольное приложение (.Net Core) и библиотеку классов (.Net Core), System.ServiceModel недоступен. Я немного погуглил, но не понял, что «заменяет» WCF в этом случае.
Как мне предоставить Add(int x, int y)
функцию в библиотеке классов консольному приложению в .Net Core? Я вижу System.ServiceModel.Web, и, поскольку это пытается быть кросс-платформенным, мне нужно создавать службу RESTful?
do I have to create a RESTful service?
- AFAIK да (или используйте какое-то стороннее решение, которое я бы не знал для .NET Core)Ответы:
WCF не поддерживается в .NET Core, поскольку это технология, специфичная для Windows, а .NET Core должен быть кроссплатформенным.
Если вы реализуете межпроцессное взаимодействие, попробуйте проект IpcServiceFramework .
Это позволяет создавать такие сервисы в стиле WCF:
Создать контракт на обслуживание
public interface IComputingService { float AddFloat(float x, float y); }
Внедрить услугу
class ComputingService : IComputingService { public float AddFloat(float x, float y) { return x + y; } }
Разместите службу в консольном приложении
class Program { static void Main(string[] args) { // configure DI IServiceCollection services = ConfigureServices(new ServiceCollection()); // build and run service host new IpcServiceHostBuilder(services.BuildServiceProvider()) .AddNamedPipeEndpoint<IComputingService>(name: "endpoint1", pipeName: "pipeName") .AddTcpEndpoint<IComputingService>(name: "endpoint2", ipEndpoint: IPAddress.Loopback, port: 45684) .Build() .Run(); } private static IServiceCollection ConfigureServices(IServiceCollection services) { return services .AddIpc() .AddNamedPipe(options => { options.ThreadCount = 2; }) .AddService<IComputingService, ComputingService>(); } }
Вызов службы из клиентского процесса
IpcServiceClient<IComputingService> client = new IpcServiceClientBuilder<IComputingService>() .UseNamedPipe("pipeName") // or .UseTcp(IPAddress.Loopback, 45684) to invoke using TCP .Build(); float result = await client.InvokeAsync(x => x.AddFloat(1.23f, 4.56f));
источник
Вы можете использовать gRPC для размещения веб-сервисов внутри основного приложения .NET.
Введение
пример
Код сервера
class Program { static void Main(string[] args) { RunAsync().Wait(); } private static async Task RunAsync() { var server = new Grpc.Core.Server { Ports = { { "127.0.0.1", 5000, ServerCredentials.Insecure } }, Services = { ServerServiceDefinition.CreateBuilder() .AddMethod(Descriptors.Method, async (requestStream, responseStream, context) => { await requestStream.ForEachAsync(async additionRequest => { Console.WriteLine($"Recieved addition request, number1 = {additionRequest.X} --- number2 = {additionRequest.Y}"); await responseStream.WriteAsync(new AdditionResponse {Output = additionRequest.X + additionRequest.Y}); }); }) .Build() } }; server.Start(); Console.WriteLine($"Server started under [127.0.0.1:5000]. Press Enter to stop it..."); Console.ReadLine(); await server.ShutdownAsync(); } }
Код клиента
class Program { static void Main(string[] args) { RunAsync().Wait(); } private static async Task RunAsync() { var channel = new Channel("127.0.0.1", 5000, ChannelCredentials.Insecure); var invoker = new DefaultCallInvoker(channel); using (var call = invoker.AsyncDuplexStreamingCall(Descriptors.Method, null, new CallOptions{})) { var responseCompleted = call.ResponseStream .ForEachAsync(async response => { Console.WriteLine($"Output: {response.Output}"); }); await call.RequestStream.WriteAsync(new AdditionRequest { X = 1, Y = 2}); Console.ReadLine(); await call.RequestStream.CompleteAsync(); await responseCompleted; } Console.WriteLine("Press enter to stop..."); Console.ReadLine(); await channel.ShutdownAsync(); } }
Общие классы между клиентом и сервером
[Schema] public class AdditionRequest { [Id(0)] public int X { get; set; } [Id(1)] public int Y { get; set; } } [Schema] public class AdditionResponse { [Id(0)] public int Output { get; set; } }
Дескрипторы услуг
using Grpc.Core; public class Descriptors { public static Method<AdditionRequest, AdditionResponse> Method = new Method<AdditionRequest, AdditionResponse>( type: MethodType.DuplexStreaming, serviceName: "AdditonService", name: "AdditionMethod", requestMarshaller: Marshallers.Create( serializer: Serializer<AdditionRequest>.ToBytes, deserializer: Serializer<AdditionRequest>.FromBytes), responseMarshaller: Marshallers.Create( serializer: Serializer<AdditionResponse>.ToBytes, deserializer: Serializer<AdditionResponse>.FromBytes)); }
Сериализатор / десериализатор
public static class Serializer<T> { public static byte[] ToBytes(T obj) { var buffer = new OutputBuffer(); var writer = new FastBinaryWriter<OutputBuffer>(buffer); Serialize.To(writer, obj); var output = new byte[buffer.Data.Count]; Array.Copy(buffer.Data.Array, 0, output, 0, (int)buffer.Position); return output; } public static T FromBytes(byte[] bytes) { var buffer = new InputBuffer(bytes); var data = Deserialize<T>.From(new FastBinaryReader<InputBuffer>(buffer)); return data; } }
Выход
Пример вывода клиента
Пример вывода сервера
Ссылки
Контрольные точки
источник
gRPC
виду, что на данный момент не компилируется с собственной цепочкой инструментов .net в VS 2019 (16.0.2) и, следовательно, не будет работать с UWP.Похоже, что будет проект CoreWCF, поддерживаемый .NET Foundation при поддержке Microsoft.
Дополнительные сведения см. В статье «Приветствие Core WCF в .NET Foundation».
Первоначально будут реализованы только транспорт netTcp и http.
источник
WCF делает много вещей; это простой способ удаленного вызова процедур между двумя приложениями (процессами) на одной машине, используя именованные каналы; это может быть внутренний канал связи клиент-сервер большого объема между компонентами .NET, использующий двоичную сериализацию по TCPIP; или он может предоставлять стандартизованный кросс-технологический API, например, через SOAP. Он даже поддерживает такие вещи, как асинхронный обмен сообщениями через MSMQ.
Для .NET Core существуют разные замены в зависимости от цели.
Для кросс-платформенного API вы должны заменить его службой REST с использованием ASP.NET.
Для межпроцессных соединений или соединения клиент-сервер хорошо подойдет gRPC, с отличным ответом @Gopi.
Итак, ответ на вопрос «Что заменяет WCF» зависит от того, для чего вы его используете.
источник
Существует репозиторий сообщества https://github.com/CoreWCF/CoreWCF, в котором реализованы некоторые части WCF. Вы можете использовать его для поддержки некоторых простых служб WCF. Однако не все функции поддерживаются.
источник
Итак, из моего исследования лучшее решение не имеет автоматически сгенерированных классов прокси. Это лучшее решение - создать службу RESTful и сериализовать тело ответа в объекты модели. Где модели - это обычные объекты модели, найденные в шаблоне проектирования MVC.
Спасибо за ваши ответы
источник
Вы также можете самостоятельно разместить веб-API ASP.NET Core.
<!-- SelfHosted.csproj --> <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp3.1</TargetFramework> </PropertyGroup> <ItemGroup> <!-- see: https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#framework-reference --> <FrameworkReference Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.1.0" /> </ItemGroup> </Project>
// Program.cs using System.IO; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; namespace SelfHosted { class Program { static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) { // see: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-3.1 return Host.CreateDefaultBuilder(args) .ConfigureHostConfiguration(configHost => { configHost.SetBasePath(Directory.GetCurrentDirectory()); configHost.AddJsonFile("appsettings.json", optional: true); configHost.AddEnvironmentVariables(prefix: "SelfHosted_"); configHost.AddCommandLine(args); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.CaptureStartupErrors(true); webBuilder.UseStartup<Startup>(); }); } } }
// Startup.cs using System; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; namespace SelfHosted { public class Startup { public Startup(IConfiguration configuration, IWebHostEnvironment env) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { // see: https://github.com/aspnet/AspNetCore.Docs/tree/master/aspnetcore/web-api/index/samples/3.x services.AddControllers(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } } }
// Controllers\TestController.cs using System.Net.Mime; using Microsoft.AspNetCore.Mvc; namespace SelfHosted.Controllers { [ApiController] [Produces(MediaTypeNames.Application.Json)] [Route("[controller]")] public class HelloController : SelfHostedControllerBase { [HttpGet] public ActionResult<string> HelloWorld() => "Hello World!"; [HttpGet("{name}")] public ActionResult<string> HelloName(string name) => $"Hello {name}!"; } }
источник
Доступен порт .NET Core: https://github.com/dotnet/wcf Он все еще находится на стадии предварительной версии, но они активно его разрабатывают.
источник
На сегодняшний день все доступные WCFCore selfhost не так просты в установке и использовании.
Лучше всего для HostedService это будут альтернативы, как gRPC показал в предыдущем ответе, и обратите внимание, что за 1 год можно многое изменить, если WCF поддерживается в Core только как клиент, который работает нормально.
источник