If I do not use Autofac, I can connect without issues. But when I use Autofac, I get an error of
java.util.concurrent.ExecutionException: java.net.ConnectException: Connection refused`.
Here is how I setup my SignalR Server:
public class Program
{
private static ApplicationSetting mApplicationSetting;
private static ILoggingOperation mLoggingOperation;
static void Main(string[] args)
{
StartWebHost();
Console.ReadLine();
}
static void StartWebHost()
{
using (WebApp.Start("http://10.16.32.52:8085"))
{
Console.WriteLine(#"Server running at 10.16.32.52:8085");
}
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
builder.RegisterHubs(Assembly.GetExecutingAssembly()).PropertiesAutowired();
builder.RegisterType<Application>().As<IApplication>();
builder.RegisterType<CommonActions>().As<ICommonActions>();
builder.RegisterType<LoggingOperation>().As<ILoggingOperation>();
var container = builder.Build();
var resolver = new Autofac.Integration.SignalR.AutofacDependencyResolver(container);
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR(new HubConfiguration
{
Resolver = resolver,
EnableJSONP = true,
EnableDetailedErrors = true,
EnableJavaScriptProxies = true
});
}
}
My Hub is called ApplicationHub and it is in another class. What can I try next?
Related
I'm porting this service host (over TCP, non Web) from .NET Framework 4.8 to .NET Core 3.1:
using (this._host = new ServiceHost(_receiver, new Uri("net.tcp://localhost:8065")))
{
this._host.OpenTimeout = TimeSpan.FromMinutes(5);
this._host.CloseTimeout = TimeSpan.FromMinutes(5);
var binding = new NetTcpBinding
{
CloseTimeout = TimeSpan.FromSeconds(15),
OpenTimeout = TimeSpan.FromSeconds(15),
SendTimeout = TimeSpan.FromSeconds(15),
ReceiveTimeout = TimeSpan.FromSeconds(15);
};
this._host.AddServiceEndpoint(typeof(IMessageReceiver), binding, "ISubscribe");
}
But there are not channel to get in this point (old code in .NET Framework 4.8):
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single,
IncludeExceptionDetailInFaults = true)]
public class MessageReceiver : IMessageReceiver
{
...
public bool Subscribe()
{
try
{
IMessageSender callback = OperationContext.Current.GetCallbackChannel<IMessageSender>();
if (!_subscribers.Contains(callback))
{
_subscribers.Add(callback);
Console.WriteLine("Subscriber");
}
return true;
}
catch (Exception e)
{
Console.WriteLine("Subscribe Exception" + e.ToString());
return false;
}
}
...
}
And i can't port this configuration in .NET Core:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single, InstanceContextMode = InstanceContextMode.Single,
IncludeExceptionDetailInFaults = true)]
I'm trying with this:
public static IWebHostBuilder CreateHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
services.AddMessageReceiverFramework(new IPEndPoint(IPAddress.Any, 8065));
})
.UseUrls("net.tcp://localhost:8065/ISubscribe")
.UseStartup<Startup>();
public static class MessageReceiverExtensionsAux
{
public static IServiceCollection AddMessageReceiverFramework(this IServiceCollection services,
IPEndPoint endPoint)
{
services.TryAddEnumerable(ServiceDescriptor.Singleton<IConfigureOptions<KestrelServerOptions>,
MessageReceiverOptionsSetup>());
services.Configure<MessageReceiverOptions>(o =>
{
o.EndPoint = endPoint;
});
services.TryAddSingleton<IMessageReceiver, MessageReceiver>();
return services;
}
}
I looking for best strategy for mantening same behavior on client side (.NET Framework 4.8).
Any suggestion?
Very thanks.
I got CoreWCF.Http package: https://github.com/CoreWCF/CoreWCF
using CoreWCF;
using CoreWCF.Configuration;
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.ConfigureServices(services =>
{
...
}).UseKestrel(options => {
options.ListenLocalhost(8080);
}).UseNetTcp(8808)
.UseStartup<Startup>();
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddServiceModelServices();
}
public void Configure(IApplicationBuilder app, IHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseServiceModel(builder =>
{
var bind = new NetTcpBinding();
builder
.AddService<MessageReceiver>()
.AddServiceEndpoint<MessageReceiver>(typeof(IMessageReceiver),bind, "/nettcp");
});
}
}
Not implement duplex channel. But is good to me, whith new code for this inconvenience.
I am working on a prototype app. Where we are using the new Blazor WebAssembly. What I am trying to do is access my JSON file to get access to endpoints we have setup to make API calls. This is what I have currently
appsettings.json:
"Endpoints": {
"AuthEndpoint": "https://auth"
}
Program.cs:
public static async Task Main(string[] args)
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
//var endpointSettings = new EndpointSettings()
//{
// AuthEndpoint = config["Endpoints:AuthEndpoint"]
//};
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) })
.AddScoped<IAuthenticationService, AuthenticationService>()
.AddTransient(_ =>
{
return config.GetSection("Endpoints")
.Get<EndpointSettings>();
})
.AddTransient<IAuthClient, AuthClient>();
await builder.Build().RunAsync();
}
When it builds in the console log I am getting this error message
I am trying to find out why this happening and what can I do to fix it
something along these lines for example:
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args)
.Build()
.Run();
}
public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
BlazorWebAssemblyHost.CreateDefaultBuilder()
.UseBlazorStartup<Startup>();
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(GetConfiguration());
}
public void Configure(IComponentsApplicationBuilder app )
{
app.AddComponent<App>("app");
}
public APISetting GetConfiguration()
{
// Get the configuration from embedded dll.
using (var stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("appsettings.json"))
using (var reader = new System.IO.StreamReader(stream))
{
return System.Text.Json.JsonSerializer.Deserialize<APISetting>(reader.ReadToEnd());
}
}
}
where APISetting class "matches" your appsettings.json:
public class APISetting
{
public string AuthEndpoint { get; set; }
...
...
}
and appsettings.json "build action" is set as "Embedded resource"
I'm creating a project that is based on the eShopOnContainers Microservices architecture
I Made a few changes to program.cs and startup.cs according to .NET Core 3+
Program.cs:
public static IHostBuilder CreateHostBuilder(IConfiguration configuration, string[] args) =>
Host.CreateDefaultBuilder(args)
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
Startup.cs:
// ConfigureContainer is where you can register things directly
// with Autofac. This runs after ConfigureServices so the things
// here will override registrations made in ConfigureServices.
// Don't build the container; that gets done for you by the factory.
public void ConfigureContainer(ContainerBuilder builder)
{
//configure autofac
// Register your own things directly with Autofac, like:
builder.RegisterModule(new MediatorModule());
builder.RegisterModule(new ApplicationModule(Configuration));
}
Now in Startup.cs the AddCustomIntegrations() method Registers the IRabbitMQPersistentConnection which returns the DefaultRabbitMQPersistentConnection with IConnectionFactory configured
public static IServiceCollection AddCustomIntegrations(this IServiceCollection services, IConfiguration configuration)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
services.AddTransient<IIdentityService, IdentityService>();
services.AddTransient<IVehicleManagementIntegrationEventService, VehicleManagementIntegrationEventService>();
services.AddTransient<Func<DbConnection, IIntegrationEventLogService>>(
sp => (DbConnection c) => new IntegrationEventLogService(c));
services.AddSingleton<IRabbitMQPersistentConnection>(sp =>
{
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>();
var factory = new ConnectionFactory()
{
HostName = configuration["EventBusConnection"],
DispatchConsumersAsync = true
};
if (!string.IsNullOrEmpty(configuration["EventBusUserName"]))
{
factory.UserName = configuration["EventBusUserName"];
}
if (!string.IsNullOrEmpty(configuration["EventBusPassword"]))
{
factory.Password = configuration["EventBusPassword"];
}
var retryCount = 5;
if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
{
retryCount = int.Parse(configuration["EventBusRetryCount"]);
}
return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);
});
return services;
}
public static IServiceCollection AddEventBus(this IServiceCollection services, IConfiguration configuration)
{
var subscriptionClientName = configuration["SubscriptionClientName"];
services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp =>
{
var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>();
var iLifetimeScope = sp.GetRequiredService<ILifetimeScope>();
var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>();
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>();
var retryCount = 5;
if (!string.IsNullOrEmpty(configuration["EventBusRetryCount"]))
{
retryCount = int.Parse(configuration["EventBusRetryCount"]);
}
return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, iLifetimeScope, eventBusSubcriptionsManager, subscriptionClientName, retryCount);
});
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>();
return services;
}
When I run the application I get the following error:
Autofac.Core.DependencyResolutionException: An exception was thrown while activating IFMS.GMT.BuildingBlocks.Infrastructure.Events.EventBusRabbitMQ.EventBusRabbitMQ -> IFMS.GMT.BuildingBlocks.Infrastructure.Events.EventBusRabbitMQ.DefaultRabbitMQPersistentConnection.
---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'IFMS.GMT.BuildingBlocks.Infrastructure.Events.EventBusRabbitMQ.DefaultRabbitMQPersistentConnection' can be invoked with the available services and parameters:
Cannot resolve parameter 'RabbitMQ.Client.IConnectionFactory connectionFactory' of constructor 'Void .ctor(RabbitMQ.Client.IConnectionFactory, Microsoft.Extensions.Logging.ILogger`1[IFMS.GMT.BuildingBlocks.Infrastructure.Events.EventBusRabbitMQ.DefaultRabbitMQPersistentConnection], Int32)'.
Autofac cant seem to find the service registered with AddCustomIntegrations()
I Moved all the code from AddCustomIntegrations() and AddEventBus() to a separate Module class that inherites from Autofac.Module class and it worked
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<InMemoryEventBusSubscriptionsManager>()
.As<IEventBusSubscriptionsManager>()
.InstancePerLifetimeScope();
builder.Register<IRabbitMQPersistentConnection>(fff =>
{
var logger = fff.Resolve<ILogger<DefaultRabbitMQPersistentConnection>>();
var factory = new ConnectionFactory()
{
HostName = Configuration["EventBusConnection"],
DispatchConsumersAsync = true
};
if (!string.IsNullOrEmpty(Configuration["EventBusUserName"]))
{
factory.UserName = Configuration["EventBusUserName"];
}
if (!string.IsNullOrEmpty(Configuration["EventBusPassword"]))
{
factory.Password = Configuration["EventBusPassword"];
}
var retryCount = 5;
if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"]))
{
retryCount = int.Parse(Configuration["EventBusRetryCount"]);
}
return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount);
});
}
I've just implemented DI using Ninject for my self-hosted SignalR2 project.
public class NinjectSignalRDependencyResolver : DefaultDependencyResolver
{
private readonly IKernel _kernel;
public NinjectSignalRDependencyResolver(IKernel kernel)
{
_kernel = kernel;
}
public override object GetService(Type serviceType)
{
return _kernel.TryGet(serviceType) ?? base.GetService(serviceType);
}
public override IEnumerable<object> GetServices(Type serviceType)
{
return _kernel.GetAll(serviceType).Concat(base.GetServices(serviceType));
}
}
And my Startup class:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
var kernel = new StandardKernel();
var resolver = new NinjectSignalRDependencyResolver(kernel);
kernel.Bind<MyDbContext>().ToSelf();
kernel.Bind<IRealTimeDataEngine>().To<RealTimeDataEngine>().InSingletonScope();
kernel.Bind<IHistoricalDataEngine>().To<HistoricalDataEngine>().InSingletonScope();
kernel.Bind(typeof(IHubConnectionContext<dynamic>)).ToMethod(context =>
resolver.Resolve<IConnectionManager>().GetHubContext<MyHub>().Clients
).WhenInjectedInto<IRealTimeDataEngine>();
var config = new HubConfiguration {Resolver = resolver};
ConfigureSignalR(app, config);
}
public static void ConfigureSignalR(IAppBuilder app, HubConfiguration config)
{
app.MapSignalR(config);
}
}
In my signalr hub constructor I expect an IRealTimeDataEngine.
public MyHub(IRealTimeDataEngine realTimeDataEngine, IHistoricalDataEngine historicalDataEngine)
In my host, which is a console application, I need the same IRealTimeDataEngine to be injected.
public DummyProvider(IRealTimeDataEngine realTimeDataEngine)
In my Main method I need to create a DummyProvider object.
If I'm not mistaken, creating a new kernel would not give me the same object in the two different projects, so how should I ask for the same IRealTimeDataEngine at my composition root?
You're right you must use only one kernel per application. That means you should create your kernel outside of Startup class in your case. This can be achieved by using overloaded call of WebApp.Start method like:
class Program
{
static void Main(string[] args)
{
var kernel = new StandardKernel();
var server = WebApp.Start("http://localhost:8080/", (appBuilder) =>
{
var resolver = new NinjectSignalRDependencyResolver(kernel);
var config = new HubConfiguration {Resolver = resolver};
...
});
...
OwinStartup.cs
public class OwinStartup
{
internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
public void Configuration(IAppBuilder app)
{
DataProtectionProvider = app.GetDataProtectionProvider();
var config = new HttpConfiguration();
SimpleInjectorConfig.Configure(app);
ConfigureOAuth(app);
WebApiConfig.Register(config);
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(config);
}
private static void ConfigureOAuth(IAppBuilder app)
{
app.CreatePerOwinContext(
() => (IDisposable)GlobalConfiguration.Configuration.DependencyResolver.GetService(
typeof(AppUserManager)));
var options = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new AppAuthProvider(),
AllowInsecureHttp = true,
};
app.UseOAuthAuthorizationServer(options);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
SimpleInjectorConfig.cs
public static class SimpleInjectorConfig
{
public static void Configure(IAppBuilder app)
{
var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
//allows scoped instances to be resolved during OWIN request
app.Use(async (context, next) =>
{
using (AsyncScopedLifestyle.BeginScope(container))
{
await next();
}
});
container.Register<AppIdentityDbContext>(Lifestyle.Scoped);
container.Register<AppUserManager>(Lifestyle.Scoped);
container.Register(
() =>
container.IsVerifying
? new OwinContext().Authentication
: HttpContext.Current.GetOwinContext().Authentication, Lifestyle.Scoped);
container.Register<AppSignInManager>(Lifestyle.Scoped);
container.Verify();
GlobalConfiguration.Configuration.DependencyResolver =
new SimpleInjectorWebApiDependencyResolver(container);
}
}
So in my implemenation of OAuthAuthorizationServerProvider called AppAuthProvider Im trying to get instance of AppUserManager ( I need to find user ) using this code:
var manager = context.OwinContext.Get<AppUserManager>();
But dont know why I still get null. I really dont know what to do because everythings seems to be configured correctly. Any ideas ? Thanks !
I found a solution. Updated code below:
OwinStartup.cs
public class OwinStartup
{
internal static IDataProtectionProvider DataProtectionProvider { get; private set; }
public void Configuration(IAppBuilder app)
{
DataProtectionProvider = app.GetDataProtectionProvider();
var container = SimpleInjectorConfig.Configure();
//allows scoped instances to be resolved during OWIN request
app.Use(async (context, next) =>
{
using (AsyncScopedLifestyle.BeginScope(container))
{
await next();
}
});
var config = new HttpConfiguration
{
DependencyResolver = new SimpleInjectorWebApiDependencyResolver(container)
};
ConfigureOAuth(app, config);
WebApiConfig.Register(config);
app.UseCors(CorsOptions.AllowAll);
app.UseWebApi(config);
}
private static void ConfigureOAuth(IAppBuilder app, HttpConfiguration config)
{
app.CreatePerOwinContext(
() => (AppUserManager)config.DependencyResolver.GetService(
typeof(AppUserManager)));
var options = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new AppAuthProvider(),
//TODO: Change in production.
AllowInsecureHttp = true,
};
app.UseOAuthAuthorizationServer(options);
app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
}
}
SimpleInjectorConfig.cs
public static class SimpleInjectorConfig
{
public static Container Configure()
{
var container = new Container();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
container.Register<AppIdentityDbContext>(Lifestyle.Scoped);
container.Register<AppUserManager>(Lifestyle.Scoped);
container.Register(
() =>
container.IsVerifying
? new OwinContext().Authentication
: HttpContext.Current.GetOwinContext().Authentication, Lifestyle.Scoped);
container.Register<AppSignInManager>(Lifestyle.Scoped);
container.Verify();
return container;
}
}
Maybe someone will use it.