Windsor & NServiceBus - castle-windsor

I'm going to use NServiceBus and I'd like to use Windsor as "Builder"
I read a lot of posts in the past about bugs & incompatiblity concerning handler creation vs lifestyle.
I also read about fixing and new releases.
I'd like to be advised about the status of the integration.
Which are the builds (NServiceBus / Windsor) that are going along well?
Is http://nuget.org/packages/NServiceBus.CastleWindsor/3.3.5 a good and stable start?
Is there any contrib sample to use those 2 guys within a MVC3 project?
Thanks a lot.

Yes, http://nuget.org/packages/NServiceBus.CastleWindsor/3.3.5 is the latest stable version of Windsor + NServiceBus integration, this package was tested against Castle.Windsor v3.0.0.4001
Using NServiceBus + Windsor in a MVC3 project should be pretty easy, see this sample as a starting point.
All you should need to do is reference the nuget package and change in the Global.asax.cs the Application_Start() to use the Windsor container, for example:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// NServiceBus configuration
Configure.WithWeb()
.CastleWindsorBuilder()
.ForMvc()
.JsonSerializer()
.Log4Net()
.MsmqTransport()
.IsTransactional(false)
.PurgeOnStartup(true)
.UnicastBus()
.ImpersonateSender(false)
.CreateBus()
.Start(() => Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>().Install());
}

Related

UnknownClass.Cucumber while running JUnit engine + Cucumber + Gradle tests from command line

Me and my team just moved from JUnit4 to JUnit5 and we faced with parallelism issues. With 4th version we used -Dcucumber.options="--threads 5" to run in tests several threads, but after deprecation and removing of cucumber options it's obviously doesn't work anymore. I set up (at least I think so) junit platform engine for the project (https://github.com/cucumber/cucumber-jvm/tree/main/cucumber-junit-platform-engine#configuration-options), but when I try to run tests via comand line (using Gradle task), I receive following error:
UnknownClass.Cucumber > UnknownClass.initializationError FAILED
org.junit.platform.commons.JUnitException at EngineExecutionOrchestrator.java:114
Caused by: org.junit.platform.commons.JUnitException at HierarchicalTestEngine.java:57
Caused by: org.junit.platform.commons.JUnitException at DefaultParallelExecutionConfigurationStrategy.java:41
Unfortunately, didn't find something in the internet, maybe someone can help with it?
What we use:
Spring boot 2.7.3
Gradle 7.5.1
Cucumber java, junit, spring, junit-platform-engine 5.7.0
junit-platform-suite-api 1.3.2
Tasks in build.gradle that I have now:
useJUnitPlatform()
systemProperty("cucumber.junit-platform.naming-strategy", "long")
systemProperty("cucumber.execution.parallel.enabled", true)
systemProperty("cucumber.execution.parallel.config.strategy", "fixed")
systemProperty("cucumber.plugin", "html:reports/html")
systemProperty("cucumber.plugin", "pretty")
systemProperty("cucumber.plugin", "junit:reports/junit")
doLast {
javaexec {
mainClass.set("io.cucumber.core.cli.Main")
classpath = cucumberRuntime + sourceSets.test.get().output + sourceSets.main.get().output
}
}
}
tasks {
val consoleLauncherTest by registering(JavaExec::class) {
dependsOn(testClasses)
val reportsDir = file("$buildDir/test-results")
outputs.dir(reportsDir)
classpath = sourceSets["test"].runtimeClasspath
mainClass.set("org.junit.platform.console.ConsoleLauncher")
args("--scan-classpath")
args("--include-engine", "cucumber")
args("--reports-dir", reportsDir)
}
test {
dependsOn(consoleLauncherTest)
exclude("**/*")
}
}
Configuration class:
#CucumberContextConfiguration
#Suite
#IncludeEngines("cucumber")
#SelectClasspathResource("com/example")
#ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example")
#SpringBootTest
#ContextConfiguration(classes = [IntegrationContext::class], loader = SpringBootContextLoader::class)
class Application() {}
Your question is pretty much impossible to answer because you didn't go through the process of making a minimal reproducer. For your next question please read the "Help others reproduce the problem" section in How do I ask a good question?.
With 4th version we used -Dcucumber.options="--threads 5" to run in tests several threads, but after deprecation and removing of cucumber options it's obviously doesn't work anymore.
Project typically include a CHANGELOG and release notes documenting all relevant changes.
What we use:
Spring boot 2.7.3
Cucumber java, junit, spring, junit-platform-engine 5.7.0
junit-platform-suite-api 1.3.2
These dependencies don't converge and aren't quite correct. You'll want to use Cucumber's and JUnit's Bill of Materials to avoid having to specify the version for every module.
If you're using Spring Boot in the recommended way you may also be able to omit the junit-bom altogether.
dependencies {
testImplementation(platform("org.junit:junit-bom:5.9.1"))
testImplementation(platform("io.cucumber:cucumber-bom:7.9.0"))
testImplementation("io.cucumber:cucumber-java")
testImplementation("io.cucumber:cucumber-junit-platform-engine")
testImplementation("org.junit.platform:junit-platform-suite")
testImplementation("org.junit.jupiter:junit-jupiter")
}
Tasks in build.gradle that I have now:
So in this build file it appears that you are trying to run Cucumber in 3 different ways. Through the JUnit Platform, through Cucumbers CLI and through the JUnit 5 ConsoleLauncher.
I don't know which solution you are trying use but suppose that you want to use the JUnit Platform, then you look at cucumber-java-skeleton for a working example.
Then afterwards you should clean up your build file. :D

Generate Razor HTML emails in dotnet core 2

How can you generate emails (html) using Razor in dotnetcore - and not from an MVC app (think from a console app)?
RazorEngine does a great job in .net 4.x, but is not working in dotnet core.
RazorEngineLight works in dotnet core 1.x, but not in 2.x.
Some other options are mentioned in this post: Using Razor outside of MVC in .NET Core but none of them actually work in .net core 2.0
Edit two years later:
In case somebody comes here looking for answers on this... I (OP) have stopped entirely relying on Razor to generate emails using templates etc. It is very fragile and error-prone - a non-stop headache. I prefer Mandrill or Sendgrid these days - using templates.
In a comment on this provided answer from the link provided you stated
I am not able to get this to work. I get the error: Unable to resolve service for type 'Microsoft.AspNetCore.Mvc.Razor.IRazorViewEngine' while attempting to activate 'Mvc.RenderViewToString.RazorViewToStringRenderer'.'
This normally indicates that a required service was not registered with the service collection so the provider is unable to resolve the service when needed.
That answer did not refer to the additional service configuration and only had
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<IViewRender, ViewRender>();
}
as it was already being run in an Asp.Net Core environment, which meant that the services manually added in the console application were already being done in start up.
Pay attention to this snippet from the answer that was linked to from the answer you commented on.
private static void ConfigureDefaultServices(IServiceCollection services) {
var applicationEnvironment = PlatformServices.Default.Application;
services.AddSingleton(applicationEnvironment);
var appDirectory = Directory.GetCurrentDirectory();
var environment = new HostingEnvironment
{
WebRootFileProvider = new PhysicalFileProvider(appDirectory),
ApplicationName = "RenderRazorToString"
};
services.AddSingleton<IHostingEnvironment>(environment);
services.Configure<RazorViewEngineOptions>(options =>
{
options.FileProviders.Clear();
options.FileProviders.Add(new PhysicalFileProvider(appDirectory));
});
services.AddSingleton<ObjectPoolProvider, DefaultObjectPoolProvider>();
var diagnosticSource = new DiagnosticListener("Microsoft.AspNetCore");
services.AddSingleton<DiagnosticSource>(diagnosticSource);
services.AddLogging();
services.AddMvc();
services.AddSingleton<RazorViewToStringRenderer>();
}
The important part above is
services.AddMvc();
That will add the relevant view engine dependencies to the service collection
MvcServiceCollectionExtensions.cs
public static IMvcBuilder AddMvc(this IServiceCollection services) {
//...code removed for brevity
// Default framework order
builder.AddFormatterMappings();
builder.AddViews();
builder.AddRazorViewEngine();
builder.AddRazorPages();
builder.AddCacheTagHelper();
//...code removed for brevity
}
Everything else as currently presented is sound and should work as intended.
You should review
https://github.com/aspnet/Entropy/tree/93ee2cf54eb700c4bf8ad3251f627c8f1a07fb17/samples/Mvc.RenderViewToString
and follow a similar structure to get the code to work in your scenario. From there you can start making your custom modification and monitor where it breaks.
The modular nature of .Net Core allows for such customizations as the different modules can be stripped out and used in other environments.

.NET Core Configuration - System.Net connectionManagement/maxconnections?

I am migrating a console app (REST client app) from .NET framework to .NET Core.
In my current (framework) version, I use the app.config file to set the System.Net configuration:
<system.net>
<connectionManagement>
<add address="*" maxconnection="65535"/>
</connectionManagement>
</system.net>
In .NET Core, I have to use a JSON file for configuration. There is no documentation for implementing these settings using the new configuration schema. Does anyone know how this might look inside the new JSON config, or the correct way to implement this in Core? Do I need to build a designated "System.Net.json" config file (separate from an AppSettings.json) specifically to do this?
Thanks.
I assume you're trying to avoid the limit of 2 connections per endpoint, which is default on .NET Framework. Such limit does not exist on .NET Core. So you don't need the above setting at all.
Note that to achieve better perf, we recommend to use HttpClient/HttpClientHandler over HttpWebRequest/ServicePoint on .NET Core. HttpWebRequest/ServicePoint APIs are compat-only.
If you want to limit HttpClient connections, then use HttpClientHandler.MaxConnectionsPerServer
Assuming you are using Kestrel as your web server (and not doing it through IIS implementation), you should be able to set this in your UseKestrel in your BuildWebHost.
It would go something like this:
.UseKestrel(options =>
{
options.Limits.MaxConcurrentConnections = 100;
})
You can also add this in your HttpClientHandler, It's called MaxConnectionsPerServer. It can be seen here.
Some addition to Karel Zikmund answer. (As i don’t have permissions to comment).
According to this doc connections are limited since .net core 2.0:
https://learn.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.defaultconnectionlimit?view=netcore-3.1
What is missed in doc is if ServicePointManager used for .net core HttpClient implementation. According to this info it is used in .net core, but for HttpWebRequest, not HttpClient: https://github.com/dotnet/runtime/issues/26048

IoC container that can register everything (non generic) automatically without configuration (assembly to assembly)

the idea is that I have a Core project with lots of interfaces, also Data and Service project with implementations (everything 1-to-1), e.g.:
Core { IFooRepo, IBarRepo, IFooService, IBarService}
Data {FooRepo: IFooRepo, BarRepo : IBarRepo}
Service {FooService : IFooService, BarService : IBarService}
so I would like something like
register(Core, Data);
register(Core, Service);
there are lots of IoC containers and I don't know which one of them can do this, or is closer to this solution, anybody knows ?
You are talking about auto-registration. Many IoC containers support this.
StructureMap
http://structuremap.net/structuremap/ScanningAssemblies.htm
Castle Windsor (see bottom of 2nd page of the article)
http://www.code-magazine.com/article.aspx?quickid=0906051
Autofac
http://code.google.com/p/autofac/wiki/Scanning
Ninject
Looks like you can do it via Kernel.Scan(), though I couldn't find docs. (Server was unavailable.)
How to use Ninject Conventions extension without referencing Assembly (or Types within it)
Last I looked, Unity did not support auto-registration, though that may have changed with a recent release.
UPDATE: Thanks to Mauricio for noticing that I incorrectly identified the desired feature as auto-wiring. Corrected and updated the links.
In Autofac the simplest way to achieve this is:
var builder = new ContainerBuilder();
var data = typeof(BarRepo).Assembly();
builder.RegisterAssemblyTypes(data).AsImplementedInterfaces();
var service = typeof(BarService).Assembly();
builder.RegisterAssemblyTypes(service).AsImplementedInterfactes();
var container = builder.Build();
Now this will not be selective about the service interfaces being from the Core assembly. If this really matters (it probably shouldn't) then vary the above registrations along these lines:
var core = typeof(IBarRepo).Assembly();
builder.RegisterAssemblyTypes(data)
.As(t => t.GetInterfaces()
.Where(i => i.Assembly == core)
.Select(i => new TypedService(i)));
Cheers,
Nick
Windsor lets you easily register classes as interfaces they expose, either all of them or, selectively. (see the documentation).
It does not have OOTB support for your scenario (filtering implemented interfaces to only include those from specific assembly) but (as for everything in Windsor) there's a hook you can use to easily have that.
container.Register(
AllTypes.FromAssemblyContaining<SomeClass>()
WithService.Select((type, #base) =>
type.GetAllInterfaces()
.Where(i => i.Assembly == yourInterfacesAssembly)))
);

How to get instance of service in Windsor Castle

In a multilayer application (ASP MVC: UI project, DAL project) i registered in web.config the components.
Now i have this problem: Unit of Work pattern has do be implemented and i need to get the current instance of a particular service. The registration of the services happened in the UI project, but i need to get the current instance of this service in the DAL project. How do i get this reference?
In the UI project i already needed a way to get something resolved:
container = new WindsorContainer(
new XmlInterpreter(new ConfigResource("castle"))
);
personRepository= container.Resolve<IPersonRepository>();
Would it be OK to use the same technique in the DAL project? If yes, should i write the configuration in a separate file, so that it can be accessed by all the layers(projects)?
Sorry for this (i think) naive question but it's my first project using Castle and i think i don't understand the big picture of it!
Code snippet would help a lot.
Thanks in advance!
In a nutshell: one container instance per application, one container configuration that has all the components you need for the application. If you need a service in your DAL, inject the appropriate service interface in your DAL class via constructor (if the dependency is required) or setter (if the dependency is optional).
Try really hard to avoid using a static IoC gateway, it hides the true dependencies of a component and it hampers testability.
See these related questions:
Usage of IoC Containers; specifically Windsor
Is it correct to have many Castle Windsor containers per application if those containers belong to different tiers?
Have a look at this article. It shows you how to write a static class that performs dependency resolution using Castle Windsor. You should consider putting this class in a separate project that can be referenced from both your UI and DAL projects to allow code reuse. As the article explains, your class should provide a bootstrapper facility that initializes your IoC container. In your case, this would look like:
public static class IoC
{
private WindsorContainer _container;
public static void Initialize()
{
_container = new WindsorContainer(
new XmlInterpreter(new ConfigResource("castle"))
);
}
}
The bootstrapper would be invoked from the application startup event in your UI projects Global.asax file.
The other methods for obtaining instances of objects from the container would be as per the article.