Recording from HAVIT Educational windows from 25th September 2019.
Category Archives: .NET Framework
C# Puzzle: this = new Foo();
Can you imagine a situation when this code compiles and runs?
public void Reset() { this = new Foo(); }
See the result: https://dotnetfiddle.net/JheuMu.
C# ref returns [Jiří Činčura, HAVIT Educational window, 28.3.2019]
Recording from HAVIT Educational windows from 28th March 2019. Jiří Činčura presented the ref returns in C#.
Castle Windsor – Support for ASP.NET WebForms 4.7.2
We are proud to announce Castle Windsor Support for ASP.NET WebForms.
Sources, documentation and usage example can be found on GitHub, NuGet package Havit.CastleWindsor.WebForms is in the public NuGet feed.
C# Puzzle: out parameters
This method usually outputs false
.
Can you imagine a situation where it outputs true
?
static bool Test(out int x, out int y) { x = 123; y = 45; return (x == y); }
You can find the solution in .NET Fiddle.
C# Puzzle: Exceptions
What is the output when you run this code?
try { try { throw new Exception("A"); } catch { throw new Exception("B"); } finally { throw new Exception("C"); } } catch (Exception ex) { Console.Write(ex.Message); }
See the result: https://dotnetfiddle.net/6SWPqL
Quartz.NET, Castle Windsor – LifeStyle Per Job (Scoped)
If you have ever tried to use Quartz.NET (a famous job-scheduling library) with Castle Windsor (IoC/DI container) you might need to register a component whose life-style should be bound to the job itself (LifestylePerJob). There are plenty of alternatives available which all have the same characteristics – they do not work:
- LifestylePerThread – does not reset the thread when running a new job
- BoundTo<Job>() – does not support typed factories when resolved inside the job
- BoundTo<object>() – does not support typed factories when resolved inside the job
- Quartz.IJobFactory + LifestyleScoped – does not support typed factories when resolved into the job (the scope from JobFactory is not propagated inside the job!)
There is a “simple” workaround for such scenarios. You can use LifestyleScoped but you have to begin/end the scope in the job.
If you use the job itself just as a plumbing class where the work itself is encapsulated in a separate service (and you should do this) then you can simply inject both a service-factory and the kernel and then do the scope-work in the job itself:
public class MyJob : IJob { private readonly IServiceFactory<MyService> myServiceFactory; private readonly IKernel kernel; public MyJob(IServiceFactory<MyService> myServiceFactory, IKernel kernel) { this.myServiceFactory = myServiceFactory; this.kernel = kernel; } public void Execute() { using (var scope = kernel.BeginScope()) { // use your way to work with factories ;-) using (var myService = myServiceFactory.Create()) { myService.DoWork(); } // BTW: we have an extension method myServiceFactory.ExecuteAction(service => service.DoWork()); } } }
…the MyService class has all the dependencies you need and as you use it using the factory it behaves as the pseudo-resolution-root for this scenario. You might use the kernel.Resolve+Release in the job but I always prefer not to… ;-)
References
Mocking a ConfigurationSection (or full configuration file)
In unit-tests you sometimes find yourself in a situation that you need to mock a configuration section. The ConfigurationSection
class (or your inherited class) encapsulates nicely and there is no easy way how to break it’s read-only public interface.
You might consider abstracting the whole section and/or exposing it via some kind of adapter, but sometimes you don’t need to be 100% pure and still want get some basic test coverage.
There is an obscure but functional way how to mock the ConfigurationSection (or a whole configuration file if needed):
1. Create a fake configuration file in your test project
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="mySection" type="MyConfigurationSection, MyAssembly" /> </configSections> <mySection> <identities> <identity clientId="fake_id" name="FAKE_NAME" partitionName="FAKE_PARTITION" permissions="Full" /> </identities> </mySection> </configuration>
The file can be placed in any directory in test project. Right beside your test-class might be the right place.
2. Set the configuration file to be copied to build output
In Properties of the configuration file, set:
- Build Action = Content
- Copy to Output Directory = Copy always
3. Create a unit-test which uses the file to build a fake configuration
[TestClass] public class MyServiceTests { public TestContext TestContext { get; set; } [TestMethod] [DeploymentItem("PathInTestProject\\MyServiceTests_ScenarioName.config")] public void MyService_DoSomething_ScenarioName_ExpectedBehavior() { // arrange ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap() { ExeConfigFilename = Path.Combine(TestContext.DeploymentDirectory, "MyServiceTests_ScenarioName.config") }; Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configFileMap, ConfigurationUserLevel.None); MyConfiguarionSection mySection = config.GetSection("mySection") as MyConfiguarionSection ; var sut = new MyService(mySection); // act ... } }
The basics:
- The
ConfigurationManager.OpenMappedExeConfiguration()
method allows you to use any configuration file you want. - The
[DeploymentItem(...)]
attribute copies the config file from build output to the “test deployment directory” (e.g. $(SolutionDir)\TestResults\Deploy_username 2017-09-29 22_02_39\Out\) - The
TestContext.DeploymentDirectory
contains the path whereas theTestContext
property is automatically injected with appropriate instance of the test context.