Attach to Process

DotNet

Version 1.2.0 of WriteAs.Net has been released.

This latest version now allows you to enter an API key when initializing a WriteAsClient instance. This API key will allow you to bypass the rate limiting checks on the Write.as API.

Some basic in-memory caching has also been added to the client. You can configure some of the cache settings when initializing a WriteAsClient instance. The new settings are described below:

  • cacheExpirationInSeconds determines how long data will stay in the cache before it expires. The default value for this setting is 300 seconds.
  • cacheSize determines how many objects it can store in the cache. Note that a collection of posts (List<Post>) and a single post each count as 1 item. The default value for this setting is 4.

You can install it via nuget: Install-Package WriteAs.NET -Version 1.2.0

Or via the .NET Core command line interface: dotnet add package WriteAs.NET --version 1.2.0

If you find any bugs or issues with it, please let me know. Thanks and y'all have a good weekend.

Tags: #DotNet #WriteAs #WriteAsNet

I'm working on an update to the WriteAs.Net client/wrapper library. In a previous post I talked about adding caching to it before I release a new version. I ran into some road-blocks that derailed me. I ended up pushing it off to the side to focus my time somewhere else.

The two issues that I ran into were: figuring out what the cache key was going to be for the cached object and removing the oldest object in the cache. I now have solutions for those issues.

For the cache keys, I figured I could use the method name plus the parameter values.

For clearing out the oldest cached object, I decided to make use of a generic Queue collection that could accept the cache key values. Then I could just pop-off the oldest value from the Queue and use that to remove the associated object in the cache.

And so anyway, I should have the updated version of the client/wrapper library out soon. I just need to do some more testing on it.

Tags: #DotNet #WriteAs #WriteAsNet

When working with a Windows Forms TextBox, yes I was working with a Windows Forms TextBox 😀, and you want to display updates periodically while a long task is running, you can make use of the Application.DoEvents() method.

I think a better solution is to use a BackgroundWorker class for this. But, if you're working on an unimportant utility tool or a throwaway app, using Application.DoEvents() should be good enough.

Tags: #DotNet #WindowsForms

When you just want to do a simple WCF service test, you don't need to download third party tools. You can use the WCF Test Client app that usually comes as part of a Visual Studio installation. I keep forgetting where to find it, so I'm writing it down on here to remind myself.

I had Visual Studio 2017 installed on my PC. Here is where I found the WCF Test Client app (WcfTestClient.exe):

C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE

Tags: #WCF #DotNet #VisualStudio

A week ago I was running a test and kept running into a WCF BindingConfiguration Error. I would not allow myself to check-in my code unless my tests passed. So, I battled with this error for over an hour.

The binding at system.serviceModel/bindings/basicHttpBinding does not have a configured binding named ‘BasicHttpBinding_IXXXXXX’. This is an invalid value for bindingConfiguration.

It's your basic, run of the mill, WCF BasicHttpBinding configuration error.

I double-checked my test project's app.config file and the relevant client.config files – everything looked right. I know it was a configuration issue. The error message itself made it obvious that it was a configuration issue. But everything looked right. I didn't see any issues with the config files I was looking at.

It must be noted that it was already close to midnight at this point. I was working late that day and decided to push myself by resolving to check-in my changes before the night ends. I have no doubt that being tired and sleepy didn't help.

Anyway, after awhile I realized that the service method that I was trying to test, was running inside another service. So, in addition to the test project’s app.config file, I also needed to double-check that other service’s Web.config file. When I ran into this error earlier that night, I actually updated that other Web.config file. I added the entry it needed just to cover my bases. I didn't know then that it was the Web.config file that was causing the error.

For some reason, possibly due to fatigue and needing sleep, I didn't think about checking that Web.config file again. Out of frustration, I decided to take a break and headed to the kitchen to drink a glass of water. After hanging out in the kitchen for a bit, then listening to some good music, I finally had the bright idea to check this other Web.config file again. And there it was, a typo on the BasicHttpBinding entry I added. Can't believe I didn't check on it sooner.

Lesson learned here is to take a break whenever you're stuck with a problem. Give your mind time to rest. Chances are, your subconscious will kick in and tell you what to try next. And if the problem points to a configuration issue, with WCF, it most likely is. So, check all the config files, again.

Tags: #WCF #CSharp #DotNet

I was playing around with Visual Studio 2019 and the open source ASP.NET Core blog engine Miniblog.Core. I cloned it to my local, opened it in Visual Studio 2019 and tried to build the solution. I immediately ran into the error below:

Error CS8630 Invalid 'nullable' value: 'Enable' for C# 7.3. Please use language version '8.0' or greater.

So, I looked up the error message and every Stack Overflow page I ended up on, says that I have to set the Language Version in Visual Studio. Okay, so how do I do that? I eventually found this answer, which gives you the steps to get to the Advanced Build Settings dialog box for the project.

  • Right-click YourProject, click Properties
  • Click Build if it's not already selected
  • Change Configuration to All Configurations
  • Click Advanced...
  • Change the language version

When the dialog box showed up however, it didn't give me an option to set the Language Version.

Visual Studio 2019 - Advanced Build Settings

Solution

The solution I ended up with involved manually editing the project file and adding an entry for the Language Version. So, I opened up the Miniblog.Core.csproj file and added <LangVersion>preview</LangVersion> under the <PropertyGroup> settings. It looks like this:

Setting the Language Version manually

Tags: #DotNet #VisualStudio #MiniblogCore

This is a great resource for anyone who wants to get started with C# and .NET Core.

Link: Hundreds of practical ASP.NET Core samples to learn the fundamentals

Tags: #Bookmarks #AspDotNet #DotNet #DotNetCore

In this post, I'll share my thoughts regarding the use of the Single Responsibility Principle based on my experiences with it.

The Single Responsibility Principle is one of the five design principles listed in SOLID. Gary McLean Hall in his book “Adaptive Code via C#” says,

“The single responsibility principle instructs developers to write code that has one and only one reason to change. If a class has more than one reason to change, it has more than one responsibility. Classes with more than a single responsibility should be broken down into smaller classes, each of which should have only one responsibility and reason to change.”

It is my favorite principle out of the five because of two reasons:

1. Easy to Implement

First, it is very easy to implement. You don't have to be an experienced software developer to start implementing the single responsibility principle in your code. All you need to keep in mind when writing code for a new class or sometimes even a method is, this block of code should be responsible for only one thing.

Are you writing code for a class to parse text files? Then make sure all the code in that class is oriented towards parsing text files. Are you writing code for a class that is supposed to send email notifications? Then keep the code focused on sending email notifications.

2. Better Code

Second reason is that it will always make your code better. Better in the sense that it helps decouples your classes/methods, which reduces the potential for bugs when refactoring code. This in turn also makes your code easier to test. In my experience, I have never seen code that was made worse by implementing the single responsibility principle.

Drawbacks?

The only argument or drawback I've heard to the use of this principle, is the possibility of increased maintenance of the code. Since each class is responsible for doing only one thing, you could end up with a lot more classes, methods, files and projects in your solution. Still, in my opinion, that is preferable if it means I have stable code that is less prone to bugs, than to have code that is low maintenance but is susceptible to bugs.

There is also the chance that a developer will try to implement this principle on a very simple app that doesn't need to change after it's been written. In this case, trying to implement the single responsibility principle will probably take more time and add complexity to the code. (I haven't exactly ran into a situation like this with this principle, but I think that's a possibility.) Sometimes you will have to pick and choose where and when to implement this principle, and that can only come with experience.

Example

Let me go through an example where I think the use of the single responsibility principle would help.

Say you have a business rule that needs to be implemented for various products. Say that Product A, B and C all use this business rule. One thing I've seen in my experience is that if the business rule logic is similar between Products A, B or C, some developers will opt to create just one class to implement the business rule for all products. Again the argument here is that since the business logic is the same, it is easier to maintain just one class for the specific business rule. Okay, fair enough. As long as the business rule doesn't have to change between any of the products, having one class/method for the business rule is acceptable. It is in violation of the single responsibility principle, but if the business rules won't ever change, then it is an acceptable implementation.

But what if the business rules does change for one product, say for Product C? Now you'll have to modify the one class that all products use, to accommodate changes for just one product. What this means is that while working on the new changes, you have an increased chance of introducing bugs to the rest of the products. This also means that any changes to that business rule for any one product, means you have to perform testing for all other products affected by the changes. That is extra work that could have been avoided by following the single responsibility principle.

Now what if you have to add new products that will also have the same business rule, except the new products have slightly different business rule logic in them? Will you modify the existing class to accommodate changes for the new products? If so, you'll run into the same issue above. Adding new products will almost feel like a way to introduce bugs to your code. You can avoid that by following the single responsibility principle.

With the use of the single responsibility principle, each product would have one class that implements a specific business rule. Any changes to the business rules for one product, will not affect the other products. Which means going forward, you only need to worry about testing the changes for the products that changed or the products that were added. Everything else should keep working the same way they've been working before. Stress free coding with minimal chances of introducing bugs, just the way I like it.

Tags: #CSharp #DotNet #SolidPrinciples #SoftwareDesignPrinciples

For the past month or so, I have noticed that I've been pointing out the need to do case-insensitive string comparisons in the code reviews that I've done. In light of that, I thought now would be a good time to do a refresher on string comparisons in C#.

Using the == operator

Doing string comparisons in C# is easy, and the easiest way to do it, is with the == operator.

public static void Main()
{
   string userName1 = "dino";
   string userName2 = "dino";
   bool areStringsEqual = userName1 == userName2;
   Console.WriteLine(areStringsEqual.ToString());
}

Result: True

The main drawback to this approach is that it will only do a case-sensitive comparison. So, any typo like in the sample code below, will not work.

public static void Main()
{
   string userName1 = "dino";
   string userName2 = "dinO";
   bool areStringsEqual = userName1 == userName2;
   Console.WriteLine(areStringsEqual.ToString());
}

Result: False

So, let's look at another approach to comparing strings...

Using ToUpper() or ToLower()

For quick case-insensitive string comparisons, you can call ToUpper() or ToLower() on your strings before doing the comparison using the == operator.

public static void Main()
{
   string userName1 = "dino";
   string userName2 = "DiNo";
   bool areStringsEqual = userName1.ToUpper() == userName2.ToUpper();
   Console.WriteLine(areStringsEqual.ToString());
}

Result: True

I don't see much drawbacks to using this approach, except if one of your strings is null, in which case you'll then have a NullReferenceException on your hands, like in the sample code below.

public static void Main()
{
   string userName1 = "dino";
   string userName2 = null;
   bool areStringsEqual = userName1.ToUpper() == userName2.ToUpper();
   Console.WriteLine(areStringsEqual.ToString());
}

Result: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.

Note: The exception message above might look weird, but that is because I am running the sample code on TryDotNet.

So, there is an extra step of making sure the strings are not null before you call one of its methods, like in the sample code below.

public static void Main()
{
   string userName1 = "dino";
   string userName2 = null;
   bool areStringsEqual = userName1 != null && userName2 != null && (userName1.ToUpper() == userName2.ToUpper());
   Console.WriteLine(areStringsEqual.ToString());
}

Result: False

The sample code above is still very much usable code, but having to do the null checks all the time can be tiring, which leads me to another way of doing string comparisons...

Using String.Compare

Using the static Compare method from the String class allows you to easily do a case-sensitive or case-insensitive string comparison using the ignoreCase parameter, like in the sample codes below.

Case-insensitive comparison:

public static void Main()
{
   string userName1 = "dino";
   string userName2 = "DiNo";
   bool areStringsEqual = String.Compare(userName1, userName2, ignoreCase: true) == 0;
   Console.WriteLine(areStringsEqual.ToString());
}

Result: True

Case-sensitive comparison:

public static void Main()
{
   string userName1 = "dino";
   string userName2 = "DiNo";
   bool areStringsEqual = String.Compare(userName1, userName2, ignoreCase: false) == 0;
   Console.WriteLine(areStringsEqual.ToString());
}

Result: False

The beauty of using the Compare method is that I don't even have to do null checks. So, taking the sample code above where I had to do null checks, and replacing it with a call to String.Compare, results in the much cleaner sample code below.

public static void Main()
{
   string userName1 = "dino";
   string userName2 = null;
   bool areStringsEqual = String.Compare(userName1, userName2, ignoreCase: true) == 0;
   Console.WriteLine(areStringsEqual.ToString());
}

Result: False

The only drawback to this approach is that it might be harder to read the first time around, because the String.Compare method returns an int, instead of a boolean value.

Normally when comparing strings, we are asking the question, are the strings equal? True or False? So, we are expecting a boolean value back. With the use of String.Compare method, you must compare the results to 0 to determine if the strings are equal. It might take a while to get used to, but the fact that you can throw any string object at this method and not worry about null checks and typos, to me that makes it the superior approach to string comparisons.

Which One Do I Use the Most?

When developing prototype applications or generally when I'm just testing something, I am fine with using the ToUpper() or ToLower() approach. When I'm guaranteed that none of the strings will be null, I would use the ToUpper() or ToLower() approach. Any other scenario, I prefer to use the String.Compare method.

Tags: #CSharp #DotNet

If you search for “how to delay message processing in RabbitMQ”, you'll most likely run into two possible solutions for it.

  • One solution is to make use of the message TTL argument with additional queues to route messages through. If I understood this approach correctly, you basically route your message to Queue A, where it will sit for some time before it expires and gets moved to another queue, say Queue B. Then you will have your consumer looking for messages at Queue B.
  • The second solution is to use the official RabbitMQ Delayed Message Plugin.

Both solutions presented above are valid solutions, but I ended up not implementing any of those solutions, and instead went with a solution that is configurable via the consumer application. First, my reasons for not going with the established solutions listed above.

  • I did not want to add any more queues or exchanges, especially if their purpose is to just move messages around.
  • The RabbitMQ Delayed Message Plugin as of this writing is still listed as an “experimental yet fairly stable” plugin. The “experimental” disclaimer is a matter of concern to me and I would prefer to wait until it matures enough that it is no longer called as such.
  • Lastly, I really wanted a solution that is configurable via the consumer application.

So, the solution I went with was to add a PublishDate via the message headers and then the consumer can delay message processing based on this date value.

Adding a PublishDate header value is easy, you add it to the Properties.Headers dictionary before publishing the message.

var properties = channel.CreateBasicProperties();
properties.Persistent = true;

properties.Headers = new Dictionary<string, object>();
properties.Headers.Add("PublishDate", DateTime.Now.ToString());

channel.BasicPublish(exchange: "",
    routingKey: "task_queue",
    basicProperties: properties,
    body: body);

Note that I'm adding the PublishDate value as a string, instead of a DateTime value. For some reason, adding it to the dictionary as a DateTime value causes an error. I don't remember what the error was, something about an invalid table value, so I just went with a string value.

On the consumer side, you will need to add code to retrieve the Publish Date from the headers.

consumer.Received += (model, ea) =>
{
    byte[] publishDateHeader = (byte[])ea.BasicProperties.Headers["PublishDate"];
    DateTime publishDate = Convert.ToDateTime(Encoding.UTF8.GetString(publishDateHeader));
    // Now you can delay message processing based on the publish date value

    var body = ea.Body;
    var message = Encoding.UTF8.GetString(body);
    Console.WriteLine(" [x] Received {0}", message);

    channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
};

Note that I'm first casting the header value to a byte array, before converting it to a string, then finally to a DateTime value. For some reason, adding a string as a custom header turns it into a byte array. Thankfully somebody else ran into this issue before and shared a solution for it.

With a PublishDate value available, you can now delay message processing however you would like. In my case, I opted to compare the PublishDate value to the DateTime.Now value, which allowed me to check how old the message was. For example, if a message was 5 minutes old, it has been delayed enough and gets processed right away. If the message was only a minute old, the consumer thread will wait until such time that the message was now 5 minutes old, before it processes it.

There are some drawbacks to this approach, namely, you will have to go through the Publisher/Consumer classes to add the code for handling a PublishDate header value. Depending on how your queues are structured and how many publisher-consumer class files you have, you could end up with changes to multiple files just to add this feature. On the flip side though, if only one queue needs this “delayed message processing” feature, then you'll have minimal changes while your other queues continue as is. There are probably more pros and cons to this approach that I haven't thought of. Still I prefer the flexibility with this approach as I only must worry about editing a consumer's config file and it allows me to run multiple consumers each with their own specific message processing setting.

Have you had to design a solution to delay message processing in RabbitMQ? If so, I am curious to hear what approach you went with and why. Please do share in the comments below or send me an email and we can discuss.

Tags: #CSharp #DotNet #RabbitMQ