دسته: ذخیره داده‌های موقت

  • 13 tips for delivering better tech talks | Code4IT


    Doing a tech talk is easy. Doing a good talk is harder. We’re going to see some tips to improve the delivery of your conferences.

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    I love to deliver tech talks: they help me improve both my technical and communication skills.

    Hey! If you’re starting doing tech talks, don’t miss my article Thoughts after my very first public speech where I explained what I did right and what I did wrong at my very first tech talk. Learn from my errors, and avoid them!💪

    On one hand, teaching stuff requires technical preparations: you need to know what you’re talking about, and you need to know it pretty well. Even more, you need to know some advanced stuff to give the audience something they will remember – if everything is obvious, what will they remember from your talk?

    On the other hand, tech talks require good communication skills: your job is to deliver a message to your audience, and you can do it only if your intent is clear and you avoid talking of useless (or misleading) stuff.

    But, in the end, only having good content is not enough: you need to shape the talk in a way that stimulates the attention of the public and does not bore them.

    note: I still have a lot of room for improvement, so I still have to work on myself to improve my talks!

    1- Tell what are the topics covered by your talk

    Why should someone attend your talk?

    This is a simple question, but it must be clear to you way before submitting your talk to CFPs. Usually, the best reason to attend is because of the content of the conference (unless you attend a conference only for the free pizza and swags!).

    You should always express what is the topic of your talk.

    Where, and when?

    1. In the title: the title should express what you’re going to say. «Azure DevOps: an intro to build and release pipelines» is better than «Let’s work with Azure DevOps!». Yes, it’s less fancy, but you are making the scope clear (build and release pipelines), the tool (Azure DevOps), and the difficulty of your talk (it’s an intro, not a talk that targets experts)
    2. In the description of your talk: when submitting CFP, when sharing it on social media, and everywhere else you can add some text to describe your talk, you should add some more details. For instance, «In this session, we’re gonna see how to build and release .NET Core projects with Azure DevOps pipelines, how to use PR builds, how to manage variable substitution with Variable Groups…». This will help the reader decide whether or not attending to your session.
    3. At the beginning of your talk: this is for people who forgot to read the session description. Repeat the points you’re gonna cover at the beginning of your talk, like right after the title and the slide about who are you. In this way, attendees can leave if they find out that the topic is not what they were expecting from the title. They don’t lose time on anything not interesting for them, and you don’t lose your focus watching at their bored faces.

    2- Divide the talks into smaller blocks

    Think of your own experience: are you able to keep the focus on a 1-hour long talk? Or do you get distracted after 10 minutes, start wandering with the mind, and so on?

    Well, that’s normal. Generally, people have a short attention span. This means that you cannot talk for 60 minutes about the same topic: your audience will get bored soon.

    So, you should split your talk into several smaller blocks. A good idea is to separate the sub-topics into 5 or 10 minutes slots, to help people understanding the precise topic of a block and, in case, pay less attention to that specific block (maybe because that’s a topic they already know, so not focusing 100% is fine).

    3- Wake up the audience with simple questions

    Sometimes the easiest way to regain the attention of the attendees is to ask them some simple questions: «Can you see my screen?», «Does any of you already used this tool?».

    It’s easy to reply to these questions, even without thinking too much about the answer.

    This kind of questions will wake up the audience and let them focus on what you’re saying for a bit more.

    Needless to say, avoid asking those questions too many times, and don’t repeat always the same question.

    4- Choose the right slide layout

    Many monitors and screens are now in 16:9. So remember to adapt the slide layout to that format.

    In the image below, we can see how the slide layout impacts the overall look: slides with a 4:3 layout are too small for current devices, and they just look… ugly!

    The right format impacts how the slides are viewed on different devices

    Slides in 16:9 feel more natural for many screen layouts.

    It’s a simple trick to remember, but it may have a great impact on your delivery.

    5- Don’t move hands and body if it’s not necessary

    Moving too much your body drives the attention away from the content of your talk. Avoid fidgeting, moving too much your hands and head.

    Stop fidgeting!

    Remember that every movement of your body should have a meaning. Use your movements to drive attention to a specific topic, or to imitate and explain some details.
    For instance, use your hands to simulate how some modules communicate with each other.

    When preparing your presentation, you are used to thinking of how you see the screen: you have your monitor size and resolution, and you can adjust your content based on that info.

    But you don’t know how the audience will see your screen.

    If you are doing an in-person talk, pay attention to the screens the audience sees: is the resolution fine? Do you have to increase the font size? Is it fine both for folks on the front and the last seats?

    On the contrary, when doing an online talk, you don’t know the device your audience will use: PC, tablet, smart tv, smartphone?

    This means that you can’t rely on the mouse cursor to point at a specific part of your monitor (eg: some text, a button, a menu item) as your audience may not see it.

    Where is the cursor?

    A good idea is to use some kind of tools like ZoomIt: it allows you to zoom in a part of your screen and to draw lines in a virtual layer.

    So, instead of saying «now click this button – hey, can you see my cursor?», use Zoomit to zoom on that button or, even better, to draw a rectangle or an arrow to highlight it.

    7- Pin presentation folder on Resource Explorer

    As we’ve already discussed in my article 10 underestimated tasks to do before your next virtual presentation, you should hide all the desktop icons – they tend to distract the audience. This also implies that even your folder you use to store the presentation assets has to be hidden.

    But now… Damn, you’ve just closed the folder with all the conference assets! Now you have to find it again and navigate through your personal folders.

    If you use Windows, luckily you can simply right-click on your folder, click Pin to Quick access

    Click “Pin to quick access”

    and have it displayed on the right bar of any folder you open.

    Folder displayed as Pinned Folder

    In this way, you can easily reach any folder with just one click.

    So your “main” folder will not be visible on your desktop, but you can still open it via the Quick Access panel.

    8- Stress when a topic is important

    You have created the presentation. You know why you built it, and what are the important stuff. Does your audience know what is important to remember?

    If you are talking for one hour, you are giving the public a lot of information. Some are trivia, some are niche details, some are the key point of a topic.

    So, make it clear what is important to remember and what is just a “good-to-know”.

    For instance, when talking about clean code, stress why it is important to follow a certain rule if it can be a game-changer. «Use consistent names when classes have similar meaning» and «Choose whether using tabs or spaces, and use them for all your files» are both valid tips, but the first one has a different weight compared to the latter one.

    Again, spend more time on the important stuff, and tell explicitly the audience that that part is important (and why).

    9- Use the slide space in the best way possible

    Let’s talk about the size of the slides’ font: keep it consistent or adapt it to the text and space in the slide?

    I thought that keeping it consistent was a good idea – somehow it hurts my brain seeing different sizes in different slides.

    But then I realized that there are some exceptions: for example, when a slide contains only a few words or a few points in a bullet list. In that case, you should occupy the space in a better way, to avoid all the emptiness around your text.

    Here we have 2 slides with the same font:

    Two slides with the same font size

    The first one is fine, the second one is too empty.

    Let’s adjust the font of the second slide:

    Two slides with different font size

    It’s a bit better. Not excellent, but at least the audience can read it. The text is a bit bigger, but you’ll hardly notice it.

    10- Turn off all the notifications

    It’s simple: if you are sharing your screen, you don’t want your audience to see those weird messages you receive on Discord or the spam emails on Outlook.

    So, turn off all the notifications. Of course, unless you are demonstrating how to integrate your stuff with platforms like Slack, Teams et cetera.

    11- Use the slides as a reference, not as a teleprompter

    Avoid full sentences in your slides. Nobody’s gonna read them – even more, if the audience is not paying attention!

    So, prefer putting just a few words instead of full, long sentences: you should not read your slides as if they were a teleprompter, and you should help your audience getting back on track if they lost their focus.

    Two bullet points like “Keep track of your progress” and “Fix weakness” are better than a single phrase like “Remember to use some tool to keep track of the progress of your project, so that you can find the weak points and fix them”.

    – of course, unless it is a quote: you should write the full text if it is important.

    12- “End” is the word

    We’re nearly at the end of this session.

    A simple yet powerful statement that can wake up your audience.

    When you’ve lost your focus, you get triggered by some words, like end. You unconsciously remember that you are at that conference for some reason, and you have to focus to get the most from the last minutes of the conference.

    So, try triggering the subconscious of your audience with some words like ending.

    13- Recap what you’ve explained

    Finally, you’re at the end of your talk.

    What should the audience remember from it?

    Spend some time to recap what you’ve seen, what are the key points of your conference, and what you’d like the others to remember.

    It is a good way to help the audience focus again and thinking of questions to bring to your attention.

    Wrapping up

    In this article, I’ve summarized some of the things I’ve worked on to improve my tech talks.

    There is still a lot to do, and a lot to learn. But I hope that those simple tricks will help other newbies like me to improve their talks.

    If you are interesting on learning from a great speaker, you should definitely watch Scott Hanselman’s “The Art of Speaking” course on Pluralsight.

    Do you have any other resources to share? The comment section is here for you!



    Source link

  • How to expose .NET Assembly Version via API endpoint routing | Code4IT


    Knowing the Assembly Version of the API you’ve deployed on an environment may be helpful for many reasons. We’re gonna see why, how to retrieve it, and how to expose it with Endpoint Routing (bye-bye Controllers and Actions!)

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    Sometimes it can be useful to show the version of the running Assembly in one .NET Core API endpoint: for example, when you want to know which version of your code is running in an environment, or to expose a simple endpoint that acts as a “minimal” health check.

    In this article, we’re going to see how to retrieve the assembly version at runtime using C#, then we will expose it under the root endpoint of a .NET Core API without creating an API Controller, and lastly we’ll see how to set the Assembly version with Visual Studio.

    How to get Assembly version

    To get the Assembly version, everything we need is this snippet:

    Assembly assembly = Assembly.GetEntryAssembly();
    AssemblyInformationalVersionAttribute versionAttribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
    string assemblyVersion = versionAttribute.InformationalVersion;
    

    Let’s break it down!

    The first step is to get the info about the running assembly:

    Assembly assembly = Assembly.GetEntryAssembly();
    

    The Assembly class is part of the System.Reflection namespace, so you have to declare the corresponding using statement.

    The AssemblyInformationalVersionAttribute attribute comes from the same namespace, and contains some info for the assembly manifest. You can get that info with the second line of the snippet:

    AssemblyInformationalVersionAttribute versionAttribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
    

    Lastly, we need the string that represents the assembly version:

    string assemblyVersion = versionAttribute.InformationalVersion;
    

    If you want to read more about Assembly versioning in .NET, just head to the official documentation.

    How to expose an endpoint with Endpoint Routing

    Next, we need to expose that value using .NET Core API.

    Since we’re exposing only that value, we might not want to create a new Controller with a single Action: in this case, endpoint routing is the best choice!

    In the Startup.cs file, under the Configure method, we can define how the HTTP request pipeline is configured.

    By default, for ASP.NET Core APIs, you’ll see a section that allows the engine to map the Controllers to the endpoints:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
    

    In this section, we can configure some other endpoints.

    The easiest way is to map a single path to an endpoint and specify the returned content. We can do it by using the MapGet method, which accepts a string for the path pattern and an async Delegate for the execution:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hi there!!");
        });
    
        endpoints.MapControllers();
    });
    

    In this way, we will receive the message Hi there every time we call the root of our API (because of the first parameter, /), and it happens only when we use the GET HTTP Verb, because of the MapGet method.

    Putting all together

    Now that we have all in place, we can join the two parts and return the Assembly version on the root of our API.

    Putting all together

    You could just return the string as it is returned from the versionAttribute.InformationalVersion property we’ve seen before. Or you could wrap it into an object.

    If you don’t want to specify a class for it, you can use an ExpandoObject instance and create new properties on the fly. Then, you have to serialize it into a string, and return it in the HTTP Response:

    endpoints.MapGet("/", async context =>
    {
        // get assembly version
        Assembly assembly = Assembly.GetEntryAssembly();
        AssemblyInformationalVersionAttribute versionAttribute = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
        string assemblyVersion = versionAttribute.InformationalVersion;
    
        // create the dynamic object
        dynamic result = new ExpandoObject();
        result.version = assemblyVersion;
    
        // serialize the object
        string versionAsText = JsonSerializer.Serialize(result);
    
        // return it as a string
        await context.Response.WriteAsync(versionAsText);
    });
    

    That’s it!

    Of course, if you want only the version as a string without the dynamic object, you can simplify the MapGet method in this way:

    endpoints.MapGet("/", async context =>
    {
        var version = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
        await context.Response.WriteAsync(version);
    });
    

    But, for this example, let’s stay with the full object.

    Let’s try it: update Assembly version and retrieve it from API

    After tidying up the code, the UseEndpoints section will have this form:

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            dynamic result = new ExpandoObject();
            result.version = Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
            string versionAsText = JsonSerializer.Serialize(result);
            await context.Response.WriteAsync(versionAsText);
        });
    
        endpoints.MapControllers();
    });
    

    or, if you want to clean up your code, you could simplify it like this:

    app.UseEndpoints(endpoints =>
    {
        endpoints.WithAssemblyVersionOnRoot();
        endpoints.MapControllers();
    });
    

    WithAssemblyVersionOnRoot is an extension method I created to wrap that logic and make the UseEndpoints method cleaner. If you want to learn how to create extension methods with C#, and what are some gotchas, head to this article!

    To see the result, open Visual Studio, select the API project and click alt + Enter to navigate to the Project properties. Here, under the Package tag, define the version in the Package version section.

    Tab on Visual Studio used to define assembly version

    In this screen, you can set the value of the package that will be built.

    To double-check that the version is correct, head to the bin folder and locate the exe related to your project: right-click on it, go to properties and to the details tab. Here you can see the details of that exe:

    Assembly version on exe properties

    Noticed the Product version? That’s exactly what we’ve set up on Visual Studio.

    So, now it’s time to run the application.

    Get back to Visual Studio, run the application, and navigate to the root of the API.

    Finally, we can enjoy the result!

    Assembly version as exposed by the API endpoint

    Quite simple, isn’t it?

    Wrapping up

    In this article, we’ve seen how to expose on a specific route the version of the assembly running at a specified URL.

    This is useful to help you understand which version is currently running in an environment without accessing the CD pipelines to see which version has been deployed.

    Also, you can use this information as a kind of health check, since the data exposed are static and do not depend on any input or database status: the simplest match for getting info about the readiness of your application.

    What other info would you add to the exposed object? Let me know in the comment section 👇

    Happy coding!



    Source link

  • How to choose meaningful names? | Code4IT


    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    One of the fundamentals of clean code is: use meaningful names.

    But choosing meaningful names takes time!

    Time spent finding good names is time saved trying to figure out what you meant.

    How to approach it? Good names do not come on the first try!

    My suggestion is: at first, write down the code as it comes.

    public static string Get(string input)
    {
      char[] arr = new char[input.Length];
      int i = input.Length - 1;
      foreach (var e in input)
      {
        arr[i] = e;
        i--;
      }
    
      return new String(arr);
    }
    

    And then, when you have almost everything clear, choose better names for

    • classes
    • methods
    • parameters
    • variables
    • namespaces
    • libraries
    public static string GetReversedString(string originalString)
    {
      char[] reversedChars = new char[originalString.Length];
      int currentIndex = originalString.Length - 1;
      foreach (var currentChar in originalString)
      {
        reversedChars[currentIndex] = currentChar;
        currentIndex--;
      }
    
      return new String(reversedChars);
    }
    

    Probably, you’ll never reach perfection. Sad, but true.

    You might want to add some tests to your code, right? RIGHT??

    A good moment to choose better names is while writing test: at that moment your tests act as Clients to your production code, so if you find that the name of the method does not fully represent its meaning, or the parameter names are misleading, this is a good moment to improve them.

    And don’t forget about private variables and methods!

    So, what is “a good name”?

    A good name should express:

    • its meaning (what a method does?)
    • its scope (for items in loops, even var i = 0 is acceptable, if the scope is small)
    • what it represents (originalString is, of course, the original string)

    👉 Let’s discuss it on Twitter or on the comment section below!

    🐧

    This article first appeared on Code4IT





    Source link

  • Azure Service Bus and C#


    Azure Service bus is a message broker generally used for sharing messages between applications. In this article, we’re gonna see an introduction to Azure Service Bus, and how to work with it with .NET and C#

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    Azure Service Bus is a message broker that allows you to implement queues and pub-subs topics. It is incredibly common to use queues to manage the communication between microservices: it is a simple way to send messages between applications without bind them tightly.

    In this introduction, we’re going to learn the basics of Azure Service Bus: what it is, how to create a Bus and a Queue, how to send and receive messages on the Bus with C#, and more.

    This is the first part of a series about Azure Service Bus. We will see:

    1. An introduction to Azure Service Bus with C#
    2. Queues vs Topics
    3. Handling Azure Service Bus errors with .NET

    But, for now, let’s start from the basics.

    What is Azure Service Bus?

    Azure Service Bus is a complex structure that allows you to send content through a queue.

    As you may already know, a queue is… well, a queue! First in, first out!

    This means that the messages will be delivered in the same order as they were sent.

    Queue of penguins

    Why using a queue is becoming more and more common, for scalable applications?
    Let’s consider this use case: you are developing a microservices-based application. With the common approach, communication occurs via HTTP: this means that

    • if the receiver is unreachable, the HTTP message is lost (unless you add some kind of retry policy)
    • if you have to scale out, you will need to add a traffic manager/load balancer to manage which instance must process the HTTP Request

    On the contrary, by using a queue,

    • if the receiver is down, the message stays in the queue until the receiver becomes available again
    • if you have to scale out, nothing changes, because the first instance that receives the message removes it from the queue, so you will not have multiple receivers that process the same message.

    How to create an Azure Service Bus instance

    It is really simple to create a new Service Bus on Azure!

    Just open Portal Azure, head to the Service Bus section, and start creating a new resource.

    You will be prompted to choose which subscription will be linked to this new resource, and what will be the name of that resource.

    Lastly, you will have to choose which will be the pricing tier to apply.

    Service Bus creation wizard on Azure UI

    There are 3 pricing tiers available:

    • Basic: its price depends on how many messages you send. At the moment of writing, with Basic tier you pay 0.05$ for every million messages sent.
    • Standard: Similar to the Basic tier, but allows you to have both Queues and Topics. You’ll see the difference between Queue and Topics in the next article
    • Premium: zone-redundant, with both Queues and Topics; of course, quite expensive

    So now, you can create the resource and see it directly on the browser.

    Policies and Connection Strings

    The first thing to do to connect to the Azure Service Bus is to create a Policy that allows you to perform specific operations on the Bus.

    By default, under the Shared access policies tab you’ll see a policy called RootManageSharedAccessKey: this is the default Policy that allows you to send and receive messages on the Bus.

    To get the connection string, click on that Policy and head to Primary Connection String:

    How to define Service Bus Policy via UI

    A connection string for the Service Bus looks like this:

    Endpoint=sb://c4it-testbus.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=my-secret-key
    

    Let’s break it down:

    The first part represents the Host name: this is the value you’ve set in the creation wizard, and the one you can see on the Overview tab:

    Service Bus instance Host name

    Then, you’ll see the SharedAccessKeyName field, which contains the name of the policy to use (in this case, RootManageSharedAccessKey).

    Then, we have the secret Key. If you select the Primary Connection String you will use the Primary Key; same if you use the Secondary Connection String.

    Keep that connection string handy, we’re gonna use it in a moment!

    Adding a queue

    Now that we have created the general infrastructure, we need to create a Queue. This is the core of the bus – all the messages pass through a queue.

    To create one, on the Azure site head to Entities > Queues and create a new queue.

    You will be prompted to add different values, but for now, we are only interested in defining its name.

    Write the name of the queue and click Create.

    Create queue panel on Azure UI

    Once you’ve created your queue (for this example, I’ve named it PizzaOrders), you’ll be able to see it in the Queues list and see its details.

    You can even define one or more policies for that specific queue just as we did before: you’ll be able to generate a connection string similar to the one we’ve already analyzed, with the only difference that, here, you will see a new field in the connection string, EntityPath, whose value is the name of the related queue.

    So, a full connection string will have this form:

    Service Bus connection string breakdown

    ServiceBusExplorer – and OSS UI for accessing Azure Service Bus

    How can you see what happens inside the Service Bus?

    You have two options: use the Service Bus Explorer tool directly on Azure:

    Service Bus Explorer on Azure UI

    Or use an external tool.

    I honestly prefer to use ServiceBusExplorer, a project that you can download from Chocolatey: this open source tool allows you to see what is happening inside Azure Service Bus: just insert your connection string and… voilá! You’re ready to go!

    ServiceBusExplorer project on Windows

    With this tool, you can see the status of all the queues, as well as send, read, and delete messages.

    If you want to save a connection, you have to open that tool as Administrator, otherwise, you won’t have enough rights to save it.

    How to send and receive messages with .NET 5

    To test it, we’re gonna create a simple project that manages pizza orders.
    A .NET 5 API application receives a list of pizzas to be ordered, then it creates a new message for every pizza received and sends them into the PizzaOrders queue.

    With another application, we’re gonna receive the order of every single pizza by reading it from the same queue.

    For both applications, you’ll need to install the Azure.Messaging.ServiceBus NuGet package.

    How to send messages on Azure Service Bus

    The API application that receives pizza orders from the clients is very simple: just a controller with a single action.

    [ApiController]
    [Route("[controller]")]
    public class PizzaOrderController : ControllerBase
    {
        private string ConnectionString = ""; //hidden
    
        private string QueueName = "PizzaOrders";
    
        [HttpPost]
        public async Task<IActionResult> CreateOrder(IEnumerable<PizzaOrder> orders)
        {
            await ProcessOrder(orders);
            return Ok();
        }
    }
    

    Nothing fancy, just receive a list of Pizza Orders objects with this shape:

    public class PizzaOrder
    {
        public string Name { get; set; }
        public string[] Toppings { get; set; }
    }
    

    and process those with a valid quantity.

    As you can imagine, the core of the application is the ProcessOrder method.

    private async Task ProcessOrder(IEnumerable<PizzaOrder> orders)
    {
        await using (ServiceBusClient client = new ServiceBusClient(ConnectionString))
        {
            ServiceBusSender sender = client.CreateSender(QueueName);
    
            foreach (var order in orders)
            {
                string jsonEntity = JsonSerializer.Serialize(order);
                ServiceBusMessage serializedContents = new ServiceBusMessage(jsonEntity);
                await sender.SendMessageAsync(serializedContents);
            }
        }
    }
    

    Let’s break it down.

    We need to create a client to connect to the Service Bus by using the specified Connection string:

    await using (ServiceBusClient client = new ServiceBusClient(ConnectionString))
    {
    }
    

    This client must be disposed after its use.

    Then, we need to create a ServiceBusSender object whose sole role is to send messages to a specific queue:

    ServiceBusSender sender = client.CreateSender(QueueName);
    

    Lastly, for every pizza order, we convert the object into a string and we send it as a message in the queue.

    // Serialize as JSON string
    string jsonEntity = JsonSerializer.Serialize(order);
    
    /// Create Bus Message
    ServiceBusMessage serializedContents = new ServiceBusMessage(jsonEntity);
    
    // Send the message on the Bus
    await sender.SendMessageAsync(serializedContents);
    

    Hey! Never used async, await, and Task? If you want a short (but quite thorough) introduction to asynchronous programming, head to this article!

    And that’s it! Now the message is available on the PizzaOrders queue and can be received by any client subscribed to it.

    Pizza Order message as shown on ServiceBusExplorer

    Here I serialized the PizzaOrder into a JSON string. This is not mandatory: you can send messages in whichever format you want: JSON, XML, plain text, BinaryData… It’s up to you!

    Also, you can add lots of properties to each message. To read the full list, head to the ServiceBusMessage Class documentation.

    How to receive messages on Azure Service Bus

    Once we have the messages on the Bus, we need to read them.

    To demonstrate how to read messages from a queue using C#, I have created a simple Console App, named PizzaChef. The first thing to do, of course, is to install the Azure.Messaging.ServiceBus NuGet package.

    As usual, we need a ServiceBusClient object to access the resources on Azure Service Bus. Just as we did before, create a new Client in this way:

    ServiceBusClient serviceBusClient = new ServiceBusClient(ConnectionString);
    

    This time, instead of using a ServiceBusSender, we need to create a ServiceBusProcessor object which, of course, will process all the messages coming from the Queue. Since receiving a message on the queue is an asynchronous operation, we need to register an Event Handler both for when we receive the message and when we receive an error:

    ServiceBusProcessor   _ordersProcessor = serviceBusClient.CreateProcessor(QueueName);
    _ordersProcessor.ProcessMessageAsync += PizzaItemMessageHandler;
    _ordersProcessor.ProcessErrorAsync += PizzaItemErrorHandler;
    

    For now, let’s add an empty implementation of both handlers.

    private Task PizzaItemErrorHandler(ProcessErrorEventArgs arg)
    {
    
    }
    
    private async Task PizzaItemMessageHandler(ProcessMessageEventArgs args)
    {
    
    }
    

    Note: in this article I’ll implement only the PizzaItemMessageHandler method. The PizzaItemErrorHandler, however, must be at least declared, even if empty: you will get an exception if you forget about it. Anyways, we’ll implement it in the last article of this series, the one about error handling.

    To read the content received in the PizzaItemMessageHandler method, you must simply access the Message.Body property of the args parameter:

    string body = args.Message.Body.ToString();
    

    And, from here, you can do whatever you want with the body of the message. For instance, deserialize it into an object. Of course, you can reuse the PizzaOrder class we used before, or create a new class with more properties but, still, compatible with the content of the message.

    public class ProcessedPizzaOrder
    {
        public string Name { get; set; }
        public string[] Toppings { get; set; }
    
        public override string ToString()
        {
            if (Toppings?.Any() == true)
                return $"Pizza {Name} with some toppings: {string.Join(',', Toppings)}";
            else
                return $"Pizza {Name} without toppings";
        }
    }
    

    Lastly, we need to mark the message as complete.

    await args.CompleteMessageAsync(args.Message);
    

    Now we can see the full example of the PizzaItemMessageHandler implementation:

    private async Task PizzaItemMessageHandler(ProcessMessageEventArgs args)
    {
        try
        {
            string body = args.Message.Body.ToString();
            Console.WriteLine("Received " + body);
    
            var processedPizza = JsonSerializer.Deserialize<ProcessedPizzaOrder>(body);
    
            Console.WriteLine($"Processing {processedPizza}");
    
            // complete the message. messages is deleted from the queue.
            await args.CompleteMessageAsync(args.Message);
        }
        catch (System.Exception ex)
        {
            // handle exception
        }
    }
    

    Does it work? NO.

    We forgot to start processing the incoming messages. It’s simple: in the Main method, right after the declaration of the ServiceBusProcessor object, we need to call StartProcessingAsync to start processing and, similarly, StartProcessingAsync to end the processing.

    Here’s the full example of the Main method: pay attention to the calls to Start and Stop processing.

    private static async Task Main(string[] args)
    {
        ServiceBusProcessor _ordersProcessor = null;
        try
        {
            ServiceBusClient serviceBusClient = new ServiceBusClient(ConnectionString);
    
            _ordersProcessor = serviceBusClient.CreateProcessor(QueueName);
            _ordersProcessor.ProcessMessageAsync += PizzaItemMessageHandler;
            _ordersProcessor.ProcessErrorAsync += PizzaItemErrorHandler;
            await _ordersProcessor.StartProcessingAsync();
    
            Console.WriteLine("Waiting for pizza orders");
            Console.ReadKey();
        }
        catch (Exception)
        {
            throw;
        }
        finally
        {
            if (_ordersProcessor != null)
                await _ordersProcessor.StopProcessingAsync();
        }
    }
    

    While the call to StartProcessingAsync is mandatory (otherwise, how would you receive messages?), the call to StopProcessingAsync, in a console application, can be skipped, since we are destroying the application. At least, I think so. I still haven’t found anything that says whether to call or skip it. If you know anything, please contact me on Twitter or, even better, here in the comments section – so that we can let the conversation going.

    Wrapping up

    This is part of what I’ve learned from my first approach with Azure Service Bus, and the use of Queues in microservice architectures.

    Is there anything else I should say? Have you ever used queues in your applications? As usual, feel free to drop a comment in the section below, or to contact me on Twitter.

    In the next article, we’re gonna explore another topic about Azure Service Bus, called… Topic! We will learn how to use them and what is the difference between a Queue and a Topic.

    But, for now, happy coding!



    Source link

  • how to get the index of an item in a foreach loop | Code4IT


    Do you need the index of the current item in a foreach loop with C#? Here you’ll see two approaches.

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    Sometimes, when looping over a collection of elements in C#, you need not only the items itself, but also its position in the collection.

    How to get the index of the current element in a foreach loop?

    The easiest way is to store and update the index in a separate variable

    List<string> myFriends = new List<string> {
        "Emma", "Rupert", "Daniel", "Maggie", "Alan"
    };
    
    int index = 0;
    foreach (var friend in myFriends)
    {
        Console.WriteLine($"Friend {index}: {friend}");
        index++;
    }
    

    This works fine, nothing to add.

    But, if you want something a little more elegant and compact, you can use the Select method from LINQ:

    List<string> myFriends = new List<string> {
      "Emma", "Rupert", "Daniel", "Maggie", "Alan"
    };
    
    foreach (var friend in myFriends.Select((name, index) => (name, index)))
    {
      Console.WriteLine($"Friend {friend.index}: {friend.name}");
    }
    

    Why do I like this solution?

    • it’s more compact than the first one
    • there is a tight bond between the current item in the loop and the index
    • I find it cleaner and easier to read

    Or… You can just replace it with a simple for loop!

    What about performance?

    I’ve done a simple benchmark (see here), and it resulted that for lists with less than 1000 items, the first solution is faster, and for lists with 10000 items, using LINQ is way faster than using an external index.

    Size (#items) With simple index (ms) With LINQ (ms)
    100 96 128
    1000 1225 1017
    10000 5523 786

    This happens with .NET 5.

    Update 2021-06-09: the previous benchmark was wrong!!😐

    The times listed in the previous table were misleading: I calculated those durations using a StopWatch and calling it in different methods.

    But, when performing a more precise benchmark using Benchmark.NET, the results are totally different.

    With .NET Core 3.1.14 I get the following results:

    Method array Mean Error
    WithIndex Int32[10000] 269,386.4 ns 6,168.76 ns
    WithLinq Int32[10000] 396,421.3 ns 7,778.64 ns
    WithIndex Int32[1000] 25,438.3 ns 504.03 ns
    WithLinq Int32[1000] 39,981.3 ns 1,578.48 ns
    WithIndex Int32[100] 2,440.8 ns 48.34 ns
    WithLinq Int32[100] 3,687.7 ns 73.60 ns
    WithIndex Int32[10] 185.6 ns 3.52 ns
    WithLinq Int32[10] 369.5 ns 9.51 ns

    While with .NET 5 I get these results:

    Method array Mean Error
    WithIndex Int32[10000] 134,431.02 ns 2,181.244 ns
    WithLinq Int32[10000] 273,691.68 ns 5,334.833 ns
    WithIndex Int32[1000] 12,961.69 ns 233.351 ns
    WithLinq Int32[1000] 26,023.63 ns 495.341 ns
    WithIndex Int32[100] 1,088.25 ns 21.485 ns
    WithLinq Int32[100] 2,299.12 ns 21.901 ns
    WithIndex Int32[10] 48.01 ns 0.748 ns
    WithLinq Int32[10] 228.66 ns 4.531 ns

    As you can see, actually using LINQ is slower than using a simple index. While in .NET Core 3 the results were quite similar, with .NET 5 there was a huge improvement both cases, but now using a simple index is two times faster than using LINQ.

    SORRY FOR THAT MISLEADING INFO! Thank you, Ben, for pointing it out in the comments section! 🙏

    Below you can see the code I used for this benchmark. I you want to get started with Benchmark.NET, look at the documentation or to my article Enum.HasFlag performance with BenchmarkDotNet

    public class ForeachIndexBenchmark
      {
          public IEnumerable<int[]> Arrays()
          {
              yield return Enumerable.Range(0, 10).ToArray();
              yield return Enumerable.Range(0, 100).ToArray();
              yield return Enumerable.Range(0, 1000).ToArray();
              yield return Enumerable.Range(0, 10000).ToArray();
          }
    
          [Benchmark]
          [ArgumentsSource(nameof(Arrays))]
          public void WithIndex(int[] array)
          {
              int index = 0;
              var asString = "0";
              foreach (var friend in array)
              {
                  asString = "" + index;
                  index++;
              }
          }
    
          [Benchmark]
          [ArgumentsSource(nameof(Arrays))]
          public void WithLinq(int[] array)
          {
              var asString = "0";
    
              foreach (var friend in array.Select((item, index) => (item, index)))
              {
                  asString = "" + friend.index;
              }
          }
      }
    

    This article first appeared on Code4IT

    Conclusions

    We’ve discovered that there are many ways to use indexes tightly bound with items. If you look at performance, go for the simplest ways (for loop or foreach with simple index). If you want a more concise code, go for LINQ.

    Anything else to add?

    👉 Let’s discuss it on Twitter or on the comment section below!

    🐧





    Source link

  • Queues vs Topics | Code4IT


    Queues or Topics? How are they similar and how they are different? We’ll see how to use those capabilities in Azure Service Bus with .NET and C#

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    In the previous article, we’ve seen that with Azure Service Bus, the message broker provided by Microsoft, you can send messages in a queue in a way that the first application that receives it, also removes that message from the queue.

    In this article, we’re gonna see another capability of Azure Service Bus: Topics. With topics, many different applications can read the same message from the Bus; the message will be removed from the Bus only when every application has finished processing that message.

    This is the second article in this series about Azure Service Bus:

    1. Introduction to Azure Service Bus
    2. Azure Service Bus: Queues vs Topics
    3. Handling Azure Service Bus errors with .NET

    So, now, let’s dive into Topics.

    Upgrading the Pricing Tier

    Azure Service Bus comes with 3 pricing tiers:

    • Basic: its price depends on how many messages you send. You only have Queues.
    • Standard: similar to the Basic tier, but allows you to have both Queues and Topics.
    • Premium: zone-redundant, with both Queues and Topics; of course, quite expensive.

    To use Topics, we need to upgrade our subscription tier to Standard or Premium.

    Open Portal Azure, head to the resource details of the Queue and click on the Pricing Tier section.

    Available tiers on Azure Service Bus

    Here, select the Standard tier and save.

    Queue vs Topic

    Queues and Topics are similar: when an application sends a message somewhere, a receiver on the other side reads it and performs some operations on the received message.

    But there is a key difference between Queues and Topics. With Queues, the first receiver that completes the reading of the message also removes it from the Queue so that the message cannot be processed by other readers.

    How items are processed in a Queue

    With Topics, the message is removed only after every receiver has processed the message. Every Topic has one or more Subscribers, a connection between the Topic itself and the applications. All the applications subscribe to a specific Subscription, and receive messages only from it.

    When the message is read from all the Subscribers, the message is removed from the Topic too.

    How items are processed in a Topic

    Subscriptions

    As stated on the official documentation:

    A topic subscription resembles a virtual queue that receives copies of the messages that are sent to the topic. Consumers receive messages from a subscription identically to the way they receive messages from a queue.

    This means that our applications do not access directly the Topic, as we would do if we were talking about Queues. Here we access the Subscriptions to get a copy of the message on the Topic. Once the same message has been removed from all the Subscriptions, the message is also removed from the Topic.

    This is important to remember: when using Topics, the Topic itself is not enough, you also need Subscriptions.

    Create Topics and Subscriptions on Azure

    Once we have upgraded our pricing plan to Standard, we can see the Topic button available:

    Create Topic button is now active

    Click on that button, and start creating your Topic. It’s simple, just choose its name and some optional info.

    Then, navigate to the newly created Topic page and, on the Entities panel on the right, click on Subscriptions. From here, you can manage the subscriptions related to the Topic.

    Subscriptions panel on Azure

    Click on the add button, fill the fields and… voilá! You are ready to go!

    Of course, you can see all the resources directly on the browser. But, as I’ve explained in the previous article, I prefer another tool, ServiceBusExplorer, that you can download from Chocolatey.

    Open the tool, insert the connection string, and you’ll see something like this:

    General hierarchy of Queues, Topics, and Subscriptions

    What does this structure tell us?

    Here we have a Queue, pizzaorders, which is the one we used in the previous example. Then we have a Topic: pizzaorderstopic. Linked to the Topic we have two Subscriptions: PizzaChefSubscription and PizzaInvoicesSubsciption.

    Our applications will send messages into the pizzaorderstopic Topic and read them from the two Subscriptions.

    How to use Azure Service Bus Topics in .NET

    For this article, we’re gonna rework the code we’ve seen in the previous article.

    Now we are gonna handle the pizza orders not only for the pizza chef but also for keeping track of the invoices.

    How to send a message in a Topic with CSharp

    From the developer’s perspective, sending messages on a Queue or a Topic is actually the same, so we can reuse the same code I showed in the previous article.

    We still need to instantiate a new Sender and send a message through it.

    ServiceBusSender sender = client.CreateSender(TopicName);
    
    // create a message as string
    
    await sender.SendMessageAsync(serializedContents);
    

    Of course, we must use the Topic Name instead of the Queue name.

    You can easily say that sending a message on a Topic is transparent to the client just by looking at the CreateSender signature:

    public virtual ServiceBusSender CreateSender(string queueOrTopicName);
    

    Now, if we run the application and order a new pizza, we will see that a new message is ready on the Topic, and it is waiting to be read from all the Subscriptions.

    Subscriptions with the same message ready to be read

    How to receive a message from a Topic with CSharp

    Now that the same message is available for both PizzaChefSubscription and PizzaInvoicesSubscription, we need to write the code to connect to the subscriptions.

    Again, it is similar to what we’ve seen for simple queues. We still need to instantiate a Receiver, but this time we have to specify the Topic name and the Subscription name:

    ServiceBusClient serviceBusClient = new ServiceBusClient(ConnectionString);
    
    _ordersProcessor = serviceBusClient.CreateProcessor(TopicName, SubscriptionName);
    

    The rest of the code is the same.

    As you see, we need only a few updates to move from a Queue to a Topic!

    Final result

    To see what happens, I’ve created a clone of the PizzaChef project, and I’ve named it PizzaOrderInvoices. Both projects reference the same Topic, but each of them is subscribed to its Subscription.

    When receiving a message, the PizzaChef projects prints it in this way:

    string body = args.Message.Body.ToString();
    
    var processedPizza = JsonSerializer.Deserialize<ProcessedPizzaOrder>(body);
    
    Console.WriteLine($"Processing {processedPizza}");
    
    await args.CompleteMessageAsync(args.Message);
    

    and the PizzaOrderInvoices performs the following operations:

    string body = args.Message.Body.ToString();
    
    var processedPizza = JsonSerializer.Deserialize<Pizza>(body);
    
    Console.WriteLine($"Creating invoice for pizza {processedPizza.Name}");
    
    await args.CompleteMessageAsync(args.Message);
    

    Similar things, but with two totally unrelated clients.

    So now, if we run all three applications and send a new request, we will see the same messages processed by both applications.

    Final result: the same message is read by both applications from their own subscriptions

    Wrapping up

    In this article, we’ve seen what are the differences between a Queue and a Topic when talking about Azure Service Bus.

    As we’ve learned, you can insert a new message on a Queue or on a Topic in the same way. The main difference, talking about the code, is that to read a message from a Topic you have to subscribe to a Subscription.

    Now that we’ve learned how to manage both Queues and Topics, we need to learn how to manage errors: and that will be the topic of the next article.

    Happy coding!



    Source link

  • Principle of Least Surprise | Code4IT


    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    The Principle of least surprise, also called Principle of least astonishment is a quite simple principle about Software design with some interesting aspects.

    Simplifying it a log, this principle says that:

    A function or class should do the most obvious thing you can expect from its name

    Let’s start with an example of what not to do:

    string Concatenate(string firstString, string secondString)
    {
      return string.Concat(firstString, secondString).ToLowerInvariant();
    }
    

    What is the problem with this method? Well, simply, the Client may expect to receive the strings concatenated without other modifications; but internally, the function calls the ToLowerInvariant() method on the returned string, thus modifying the expected behavior.

    So, when calling

    var first ="Abra";
    var second = "Kadabra";
    
    var concatenated = Concatenate(first, second);
    

    The concatenated variable will be abrakadabra instead of AbraKadabra.

    The solution is really simple: use better names!

    string ConcatenateInLowerCase(string firstString, string secondString)
    {
      return string.Concat(firstString, secondString).ToLowerInvariant();
    }
    

    Functions should do what you expect them to do: use clear names, clear variables, good return types.

    Related to this principle, you should not introduce unexpected side effects.

    As an example, let’s store some data on a DB, and wrap the database access with a Repository class. And let’s add an InsertItem method.

    public void InsertItem(Item newItem)
    {
      if(repo.Exists(newItem))
        repo.Update(newItem);
      else
        repo.Add(newItem);
    }
    

    Clearly, the client does not expect this method to replace an existing item. Again, the solution is to give it a better name: InsertOrUpdate, or Upsert.

    Lastly, the function should use the Design Pattern suggested by its name.

    public class RepositoryFactory
    {
        private static Repository instance = null;
        public static Repository Instance
        {
            get {
                    if (instance == null) {
                        instance = new Repository();
                    }
                    return instance;
            }
        }
    }
    

    This article first appeared on Code4IT

    See the point? It looks like we are using the Factory design pattern, but the code is actually the one for a Singleton.

    Again, being clear and obvious is one of the keys to successful clean code.

    The solution? Use better names! It may not be simple, but luckily there are some simple guidelines that you can follow.

    👉 Let’s discuss it on Twitter or on the comment section below!

    🐧





    Source link

  • Handling Azure Service Bus errors with .NET | Code4IT


    Senders and Receivers handle errors on Azure Service Bus differently. We’ll see how to catch them, what they mean and how to fix them. We’ll also introduce Dead Letters.

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    In this article, we are gonna see which kind of errors you may get on Azure Service Bus and how to fix them. We will look at simpler errors, the ones you get if configurations on your code are wrong, or you’ve not declared the modules properly; then we will have a quick look at Dead Letters and what they represent.

    This is the last part of the series about Azure Service Bus. In the previous parts, we’ve seen

    1. Introduction to Azure Service Bus
    2. Queues vs Topics
    3. Error handling

    For this article, we’re going to introduce some errors in the code we used in the previous examples.

    Just to recap the context, our system receives orders for some pizzas via HTTP APIs, processes them by putting some messages on a Topic on Azure Service Bus. Then, a different application that is listening for notifications on the Topic, reads the message and performs some dummy operations.

    Common exceptions with .NET SDK

    To introduce the exceptions, we’d better keep at hand the code we used in the previous examples.

    Let’s recall that a connection string has a form like this:

    string ConnectionString = "Endpoint=sb://<myHost>.servicebus.windows.net/;SharedAccessKeyName=<myPolicy>;SharedAccessKey=<myKey>=";
    

    To send a message in the Queue, remember that we have 3 main steps:

    1. create a new ServiceBusClient instance using the connection string
    2. create a new ServiceBusSender specifying the name of the queue or topic (in our case, the Topic)
    3. send the message by calling the SendMessageAsync method
    await using (ServiceBusClient client = new ServiceBusClient(ConnectionString))
    {
        ServiceBusSender sender = client.CreateSender(TopicName);
    
        foreach (var order in validOrders)
        {
    
            /// Create Bus Message
            ServiceBusMessage serializedContents = CreateServiceBusMessage(order);
    
            // Send the message on the Bus
            await sender.SendMessageAsync(serializedContents);
        }
    }
    

    To receive messages from a Topic, we need the following steps:

    1. create a new ServiceBusClient instance as we did before
    2. create a new ServiceBusProcessor instance by specifying the name of the Topic and of the Subscription
    3. define a handler for incoming messages
    4. define a handler for error handling
    ServiceBusClient serviceBusClient = new ServiceBusClient(ConnectionString);
    ServiceBusProcessor _ordersProcessor = serviceBusClient.CreateProcessor(TopicName, SubscriptionName);
    _ordersProcessor.ProcessMessageAsync += PizzaInvoiceMessageHandler;
    _ordersProcessor.ProcessErrorAsync += PizzaItemErrorHandler;
    await _ordersProcessor.StartProcessingAsync();
    

    Of course, I recommend reading the previous articles to get a full understanding of the examples.

    Now it’s time to introduce some errors and see what happens.

    No such host is known

    When the connection string is invalid because the host name is wrong, you get an Azure.Messaging.ServiceBus.ServiceBusException exception with this message: No such host is known. ErrorCode: HostNotFound.

    What is the host? It’s the first part of the connection string. For example, in a connection string like

    Endpoint=sb://myHost.servicebus.windows.net/;SharedAccessKeyName=myPolicy;SharedAccessKey=myKey
    

    the host is myHost.servicebus.net.

    So we can easily understand why this error happens: that host name does not exist (or, more probably, there’s a typo).

    A curious fact about this exception: it is thrown later than I expected. I was expecting it to be thrown when initializing the ServiceBusClient instance, but it is actually thrown only when a message is being sent using SendMessageAsync.

    Code is executed correctly even though the host name is wrong

    You can perform all the operations you want without receiving any error until you really access the resources on the Bus.

    Put token failed: The messaging entity X could not be found

    Another message you may receive is Put token failed. status-code: 404, status-description: The messaging entity ‘X’ could not be found.

    The reason is pretty straightforward: the resource you are trying to use does not exist: by resource I mean Queue, Topic, and Subscription.

    Again, that exception is thrown only when interacting directly with Azure Service Bus.

    Put token failed: the token has an invalid signature

    If the connection string is not valid because of invalid SharedAccessKeyName or SharedAccessKey, you will get an exception of type System.UnauthorizedAccessException with the following message: Put token failed. status-code: 401, status-description: InvalidSignature: The token has an invalid signature.

    The best way to fix it is to head to the Azure portal and copy again the credentials, as I explained in the introductory article.

    Cannot begin processing without ProcessErrorAsync handler set.

    Let’s recall a statement from my first article about Azure Service Bus:

    The PizzaItemErrorHandler, however, must be at least declared, even if empty: you will get an exception if you forget about it.

    That’s odd, but that’s true: you have to define handlers both for manage success and failure.

    If you don’t, and you only declare the ProcessMessageAsync handler, like in this example:

    ServiceBusClient serviceBusClient = new ServiceBusClient(ConnectionString);
    ServiceBusProcessor _ordersProcessor = serviceBusClient.CreateProcessor(TopicName, SubscriptionName);
    _ordersProcessor.ProcessMessageAsync += PizzaInvoiceMessageHandler;
    //_ordersProcessor.ProcessErrorAsync += PizzaItemErrorHandler;
    await _ordersProcessor.StartProcessingAsync();
    

    you will get an exception with the message: Cannot begin processing without ProcessErrorAsync handler set.

    An exception is thrown when the ProcessErrorAsync handler is not defined

    So, the simplest way to solve this error is… to create the handler for ProcessErrorAsync, even empty. But why do we need it, then?

    Why do we need the ProcessErrorAsync handler?

    As I said, yes, you could declare that handler and leave it empty. But if it exists, there must be a reason, right?

    The handler has this signature:

    private Task PizzaItemErrorHandler(ProcessErrorEventArgs arg)
    

    and acts as a catch block for the receivers: all the errors we’ve thrown in the first part of the article can be handled here. Of course, we are not directly receiving an instance of Exception, but we can access it by navigating the arg object.

    As an example, let’s update again the host part of the connection string. When running the application, we can see that the error is caught in the PizzaItemErrorHandler method, and the arg argument contains many fields that we can use to handle the error. One of them is Exception, which wraps the Exception types we’ve already seen.

    Error handling on ProcessErrorAsync

    This means that in this method you have to define your error handling, add logs, and whatever may help your application managing errors.

    The same handler can be used to manage errors that occur while performing operations on a message: if an exception is thrown when processing an incoming message, you have two choices: handle it in the ProcessMessageAsync handler, in a try-catch block, or leave the error handling on the ProcessErrorAsync handler.

    ProcessErrorEventArgs details

    In the above picture, I’ve simulated an error while processing an incoming message by throwing a new DivideByZeroException. As a result, the PizzaItemErrorHandler method is called, and the arg argument contains info about the thrown exception.

    I personally prefer separating the two error handling situations: in the ProcessMessageAsync method I handle errors that occur in the business logic, when operating on an already received message; in the ProcessErrorAsync method I handle error coming from the infrastructure, like errors in the connection string, invalid credentials and so on.

    Dead Letters: when messages become stale

    When talking about queues, you’ll often come across the term dead letter. What does it mean?

    Dead letters are unprocessed messages: messages die when a message cannot be processed for a certain period of time. You can ignore that message because it has become obsolete or, anyway, it cannot be processed – maybe because it is malformed.

    Messages like these are moved to a specific queue called Dead Letter Queue (DLQ): messages are moved here to avoid making the normal queue full of messages that will never be processed.

    You can see which messages are present in the DLQ to try to understand the reason they failed and put them again into the main queue.

    Dead Letter Queue on ServiceBusExplorer

    in the above picture, you can see how the DLQ can be navigated using Service Bus Explorer: you can see all the messages in the DLQ, update them (not only the content, but even the associated metadata), and put them again into the main Queue to be processed.

    Wrapping up

    In this article, we’ve seen some of the errors you can meet when working with Azure Service Bus and .NET.

    We’ve seen the most common Exceptions, how to manage them both on the Sender and the Receiver side: on the Receiver you must handle them in the ProcessErrorAsync handler.

    Finally, we’ve seen what is a Dead Letter, and how you can recover messages moved to the DLQ.

    This is the last part of this series about Azure Service Bus and .NET: there’s a lot more to talk about, like dive deeper into DLQ and understanding Retry Patterns.

    For more info, you can read this article about retry mechanisms on the .NET SDK available on Microsoft Docs, and have a look at this article by Felipe Polo Ruiz.

    Happy coding! 🐧



    Source link

  • String.IsNullOrEmpty or String.IsNullOrWhiteSpace? | Code4IT


    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    Imagine this: you have created a method that creates a new user in your system, like this:

    void CreateUser(string username)
    {
        if (string.IsNullOrEmpty(username))
            throw new ArgumentException("Username cannot be empty");
    
        CreateUserOnDb(username);
    }
    
    void CreateUserOnDb(string username)
    {
        Console.WriteLine("Created");
    }
    

    It looks quite safe, right? Is the first check enough?

    Let’s try it: CreateUser("Loki") prints Created, while CreateUser(null) and CreateUser("") throw an exception.

    What about CreateUser(" ")?

    Unfortunately, it prints Created: this happens because the string is not actually empty, but it is composed of invisible characters.

    The same happens with escaped characters too!

    To avoid it, you can replace String.IsNullOrEmpty with String.IsNullOrWhiteSpace: this method performs its checks on invisible characters too.

    So we have:

    String.IsNullOrEmpty(""); //True
    String.IsNullOrEmpty(null); //True
    String.IsNullOrEmpty("   "); //False
    String.IsNullOrEmpty("\n"); //False
    String.IsNullOrEmpty("\t"); //False
    String.IsNullOrEmpty("hello"); //False
    

    but also

    String.IsNullOrWhiteSpace("");//True
    String.IsNullOrWhiteSpace(null);//True
    String.IsNullOrWhiteSpace("   ");//True
    String.IsNullOrWhiteSpace("\n");//True
    String.IsNullOrWhiteSpace("\t");//True
    String.IsNullOrWhiteSpace("hello");//False
    

    As you can see, the two methods behave in a different way.

    If we want to see the results in a tabular way, we have:

    value IsNullOrEmpty IsNullOrWhiteSpace
    "Hello" false false
    "" true true
    null true true
    " " false true
    "\n" false true
    "\t" false true

    This article first appeared on Code4IT

    Conclusion

    Do you have to replace all String.IsNullOrEmpty with String.IsNullOrWhiteSpace? Probably yes, unless you have a specific reason to consider the latest three values in the table as valid characters.

    Do you have to replace it everything?

    More on this topic can be found here

    👉 Let’s discuss it on Twitter or on the comment section below.

    🐧





    Source link

  • Simplify debugging with DebuggerDisplay attribute dotNET | Code4IT


    Debugging our .NET applications can be cumbersome. With the DebuggerDisplay attribute we can simplify it by displaying custom messages.

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    Picture this: you are debugging a .NET application, and you need to retrieve a list of objects. To make sure that the items are as you expect, you need to look at the content of each item.

    For example, you are retrieving a list of Movies – an object with dozens of fields – and you are interested only in the Title and VoteAverage fields. How to view them while debugging?

    There are several options: you could override ToString, or use a projection and debug the transformed list. Or you could use the DebuggerDisplay attribute to define custom messages that will be displayed on Visual Studio. Let’s see what we can do with this powerful – yet ignored – attribute!

    Simplify debugging by overriding ToString

    Let’s start with the definition of the Movie object:

    public class Movie
    {
        public string ParentalGuide { get; set; }
        public List<Genre> Genres { get; set; }
        public string Title { get; set; }
        public double VoteAverage { get; set; }
    }
    
    public class Genre
    {
        public long Id { get; set; }
        public string Name { get; set; }
    }
    

    This is quite a small object, but yet it can become cumbersome to view the content of each object while debugging.

    General way to view the details of an object

    As you can see, to view the content of the items you have to open them one by one. When there are only 3 items like in this example, it still can be fine. But when working with tens of items, that’s not a good idea.

    Notice what is the default text displayed by Visual Studio: does it ring you a bell?

    By default, the debugger shows you the ToString() of every object. So an idea is to override that method to view the desired fields.

    public override string ToString()
    {
        return $"{Title} - {VoteAverage}";
    }
    

    This override allows us to see the items in a much better way:

    Debugging using ToString

    So, yes, this could be a way to achieve this result.

    Using LINQ

    Another way to achieve the same result is by using LINQ. Almost every C# developer has
    already used it, so I won’t explain what it is and what you can do with LINQ.

    By the way, one of the most used methods is Select: it takes a list of items and, by applying a function, returns the result of that function applied to each item in the list.

    So, we can create a list of strings that holds the info relevant to us, and then use the debugger to view the content of that list.

    IEnumerable<Movie> allMovies = GenerateMovies();
    var debuggingMovies = allMovies
            .Select(movie => $"{movie.Title} - {movie.VoteAverage}")
            .ToList();
    

    This will result in a similar result to what we’ve already seen before.

    Debugging using LINQ

    But there’s still a better way: DebuggerDisplay.

    Introducing DebuggerDisplay

    DebuggerDisplay is a .NET attribute that you can apply to classes, structs, and many more, to create a custom view of an object while debugging.

    The first thing to do to get started with it is to include the System.Diagnostics namespace. Then you’ll be able to use that attribute.

    But now, it’s time to try our first example. If you want to view the Title and VoteAverage fields, you can use that attribute in this way:

    [DebuggerDisplay("{Title} - {VoteAverage}")]
    public class Movie
    {
        public string ParentalGuide { get; set; }
        public List<Genre> Genres { get; set; }
        public string Title { get; set; }
        public double VoteAverage { get; set; }
    }
    

    This will generate the following result:

    Simple usage of DebuggerDisplay

    There are a few things to notice:

    1. The fields to be displayed are wrapped in { and }: it’s "{Title}", not "Title";
    2. The names must match with the ones of the fields;
    3. You are viewing the ToString() representation of each displayed field (notice the VoteAverage field, which is a double);
    4. When debugging, you don’t see the names of the displayed fields;
    5. You can write whatever you want, not only the fields name (see the hyphen between the fields)

    The 5th point brings us to another example: adding custom text to the display attribute:

    [DebuggerDisplay("Title: {Title} - Average Vote: {VoteAverage}")]
    

    So we can customize the content as we want.

    DebuggerDisplay with custom text

    What if you rename a field? Since the value of the attribute is a simple string, it will not notice any update, so you’ll miss that field (it does not match any object field, so it gets used as a simple text).

    To avoid this issue you can simply use string concatenation and the nameof expression:

    [DebuggerDisplay("Title: {" + nameof(Title) + "} - Average Vote: {" + nameof(VoteAverage) + "}")]
    

    I honestly don’t like this way, but it is definitely more flexible!

    Getting rid of useless quotes with ’nq’

    There’s one thing that I don’t like about how this attribute renders string values: it adds quotes around them.

    Nothing important, I know, but it just clutters the view.

    [DebuggerDisplay("Title: {Title} ( {ParentalGuide} )")]
    

    shows this result:

    DebuggerDisplay with quotes

    You can get rid of quotes by adding nq to the string: add that modifier to every string you want to escape, and it will remove the quotes (in fact, nq stands for no-quotes).

    [DebuggerDisplay("Title: {Title,nq} ( {ParentalGuide,nq} )")]
    

    Notice that I added nq to every string I wanted to escape. This simple modifier makes my debugger look like this:

    DebuggerDisplay with nq: no-quotes

    There are other format specifiers, but not that useful. You can find the complete list here.

    How to access nested fields

    What if one of the fields you are interested in is a List<T>, and you want to see one of its fields?

    You can use the positional notation, like this:

    [DebuggerDisplay("{Title} - {Genres[0].Name}")]
    

    As you can see, we are accessing the first element of the list, and getting the value of the Name field.

    DebuggerDisplay can access elements of a list

    Of course, you can also add the DebuggerDisplay attribute to the nested class, and leave to it the control of how to be displayed while debugging:

    [DebuggerDisplay("{Title} - {Genres[0]}")]
    public class Movie
    {
        public List<Genre> Genres { get; set; }
    }
    
    [DebuggerDisplay("Genre name: {Name}")]
    public class Genre
    {
        public long Id { get; set; }
        public string Name { get; set; }
    }
    

    This results in this view:

    DebuggerDisplay can be used in nested objects

    Advanced views

    Lastly, you can write complex messages by adding method calls directly in the message definition:

    [DebuggerDisplay("{Title.ToUpper()} - {Genres[0].Name.Substring(0,2)}")]
    

    In this way, we are modifying how the fields are displayed directly in the attribute.

    I honestly don’t like it so much: you don’t have control over the correctness of the expression, and it can become hard to read.

    A different approach is to create a read-only field used only for this purpose, and reference it in the Attribute:

    [DebuggerDisplay("{DebugDisplay}")]
    public class Movie
    {
        public string ParentalGuide { get; set; }
        public List<Genre> Genres { get; set; }
        public string Title { get; set; }
        public double VoteAverage { get; set; }
    
        private string DebugDisplay => $"{Title.ToUpper()} - {Genres.FirstOrDefault().Name.Substring(0, 2)}";
    }
    

    In this way, we achieve the same result, and we have the help of the Intellisense in case our expression is not valid.

    Why not overriding ToString or using LINQ?

    Ok, DebuggerDisplay is neat and whatever. But why can’t we use LINQ, or override ToString?

    That’s because of the side effect of those two approaches.

    By overriding the ToString method you are changing its behavior all over the application. This means that, if somewhere you print on console that object (like in Console.WriteLine(movie)), the result will be the one defined in the ToString method.

    By using the LINQ approach you are performing “useless” operations: every time you run the application, even without the debugger attached, you will perform the transformation on every object in the collection.This is fine if your collection has 3 elements, but it can cause performance issues on huge collections.

    That’s why you should use the DebuggerDisplay attribute: it has no side effects on your application, both talking about results and performance – it will only be used when debugging.

    Additional resources

    🔗 DebuggerDisplay Attribute | Microsoft Docs

    🔗 C# debugging: DebuggerDisplay or ToString()? | StackOverflow

    🔗 DebuggerDisplay attribute best practices | Microsoft Docs

    Wrapping up

    In this article, we’ve seen how the DebuggerDisplay attribute provided by .NET is useful to perform smarter and easier debugging sessions.

    With this Attribute, you can display custom messages to watch the state of an object, and even see the state of nested fields.

    We’ve seen that you can customize the message in several ways, like by calling ToUpper on the string result. We’ve also seen that for complex messages you should consider creating a new internal field whose sole purpose is to be used during debugging sessions.

    So, for now, happy coding!
    🐧



    Source link