Sunday, February 23, 2025

How to know when to Use Dependency Injection Lifetimes

About dependency injection (DI) lifetimes in .NET (WPF or ASP.NET Core)

AddSingleton, AddTransient, and AddScoped control how often a new instance of your registered service is created and provided to the classes that depend on it. Understanding these lifetimes is crucial for managing resources, ensuring data consistency, and optimizing performance.

Here's a breakdown of each lifetime and when to use them:

1. AddSingleton:

  • Lifetime: Creates a single instance of the service and provides that same instance to all requesting classes throughout the application's lifetime. This instance is created the first time it's requested.
  • Use Cases:
  • Stateless services: Services that don't maintain any internal state that changes (e.g., configuration providers, logging services, utility classes with static methods). Because they're stateless, the same instance can safely be shared.
  • Immutable objects: Objects whose state cannot be modified after creation. Sharing a single instance is safe because changes can't be made.
  • Caching: For caching frequently accessed data (though be very careful about cache invalidation strategies).
  • Example: A service that reads configuration settings from a file. You only need to read the file once.

C#

// Example (ASP.NET Core)
builder.Services.AddSingleton<IConfiguration>(Configuration);
// Configuration object
builder.Services.AddSingleton<ILoggerFactory, LoggerFactory>();

// Example (WPF - less common, but possible with a DI container)
services.AddSingleton<AppSettings>();
// Where AppSettings holds application-wide settings


  • Caution: Avoid using AddSingleton for services that maintain mutable state unless you specifically intend for all parts of your application to share and modify that same state. This can lead to unexpected side effects and make debugging difficult.

2. AddTransient:

  • Lifetime: Creates a new instance of the service every time it's requested.
  • Use Cases:
  • Stateful services where each request needs its own instance: Services that maintain state specific to a particular operation or request. This prevents different requests from interfering with each other's data.
  • Services that should not be shared: Services that are not thread-safe or have dependencies that shouldn't be shared.
  • Lightweight, short-lived operations: If the service is inexpensive to create, AddTransient can be a good choice.
  • Example: A service that handles a single HTTP request in ASP.NET Core or a service that performs a specific calculation in WPF.

C#

// Example (ASP.NET Core)
builder.Services.AddTransient<IOrderProcessor, OrderProcessor>();

// Example (WPF)
services.AddTransient<Calculator>();
// A calculator service


3. AddScoped:

  • Lifetime: Creates a new instance of the service once per scope. In ASP.NET Core, a scope is typically equivalent to a single HTTP request. In WPF, you can create your own scopes (less common).
  • Use Cases:
  • Data access: A database context or unit of work that should be shared within a single request but not across requests. This ensures data consistency within the request.
  • Services that need to maintain state within a request: Services that need to store data related to the current operation.
  • Preventing multiple instances of expensive resources within a scope: If creating a service is costly, AddScoped ensures it's only created once per scope.
  • Example (ASP.NET Core): An Entity Framework Core DbContext.

C#

// Example (ASP.NET Core)
builder.Services.AddScoped<ApplicationDbContext, ApplicationDbContext>();

// Example (WPF - less common, but possible)
// In WPF, you might use scopes in a more advanced scenario, perhaps related to a specific user interaction
// but it's not as common as in web applications.

Key Differences Summarized:

Note: In ASP.NET WebForms, dependency injection was not built in, so developers commonly used Autofac or other DI containers, such as Unity, Ninject, or StructureMap, to achieve similar functionality.

Lifetime

Instance Creation

Use Cases

ASP.NET Core DI

Autofac (Legacy Web API)

Singleton

Once for the entire application

Stateless services, immutable objects, caching (with caution)

AddSingleton()

SingleInstance()

Transient

Every time it's requested

Stateful services, services that should not be shared, lightweight operations

AddTransient()

InstancePerDependency()

Scoped

Once per scope (e.g., HTTP request in ASP.NET Core)

Data access, services that maintain state within a request

AddScoped()

InstancePerLifetimeScope()

Choosing the Right Lifetime:

The best lifetime depends on the specific requirements of your service. Consider these factors:

  • State: Does the service maintain state? If so, how should that state be shared (or not shared) across requests or operations?
  • Thread safety: Is the service thread-safe? If not, AddTransient or AddScoped are usually better choices.
  • Performance: Is the service expensive to create? If so, AddSingleton (for stateless services) or AddScoped can help improve performance.
  • Data consistency: Do you need to ensure that different parts of a request or operation work with the same data? AddScoped is often the answer.

If you're unsure, start with AddTransient. It's the safest option and avoids many of the potential issues associated with a shared state. You can then optimize to AddScoped or AddSingleton if necessary, but only if you understand the implications for your application's behavior. Incorrect use of lifetimes is a frequent source of bugs in DI-based applications.

How To Add a calendar ICS File Using the New Outlook

Unfortunately, as of January 2025, you can't directly add a calendar.ics file to the Outlook PWA without first downloading it.

The following steps can be used for both the PWA (Progressive Web Application) if installed on your desktop, or the Outlook for Web portal.

Here's why and what you can do:

Why it doesn't work directly:

  • Security and Sandboxing: PWAs operate in a secure environment that limits their access to your local file system. This is a core security feature to protect your data.
  • File Handling: The Outlook PWA likely hasn't fully implemented the file handling capabilities needed to open and process.ics files directly from the web.

Workarounds:

  1. Download and Import:
  • Download the.ics file to your computer.
  • Login to your PWA or Outlook Web Online account and click the calendar button in the lefthand ribbon:

  • If it’s not open already for the calendar view, click the hamburger menu and click the “Add Calendar” link:

  • Next go to Add calendar > Upload from file:

  • Select the downloaded.ics file and click the "Import" button.
  1. Subscribe (if applicable):
  • If the.ics file represents a calendar that's constantly updated (like a sports schedule or public events), see if it has a webcal link (.ics URL) instead.
  • In the Outlook PWA, go to Add calendar > Subscribe from web.

  • Paste the webcal link in the textbox.

Future Possibilities:

Microsoft is actively developing the Outlook PWA, so direct.ics importing might be added in the future. Keep an eye on updates and release notes.

If you're using the Outlook desktop app:

You can usually open an.ics file directly, and Outlook will automatically import it.

Sunday, January 19, 2025

About PowerShellGet

 

What is PowerShellGet?

  • The PowerShellGet module includes cmdlets for accessing and publishing items in the PowerShell Gallery.

  • When you use the cmdlets in the PowerShellGet module for the first time, you're prompted to install the NuGet provider. NuGet is a package manager that can obtain and install packages on Windows. The cmdlets in the PowerShellGet module use the functionality in NuGet to interact with the PowerShell Gallery.

The following table lists the two cmdlets used most often to find content in the PowerShell Gallery.

Table 1: Cmdlets used to find content in the PowerShell Gallery

Cmdlet

Description

Find-Module

Use this cmdlet to search for Windows PowerShell modules in the PowerShell Gallery. The simplest usage conducts searches based on the module name, but you can also search based on the command name, version, DscResource, and RoleCapability.

Find-Script

Use this cmdlet to search for Windows PowerShell scripts in the PowerShell Gallery. The simplest usage conducts searches based on the script name, but you can also search based on the version.

 

Private PowerShell Gallery

You can implement a private PowerShell gallery for your organization by creating your own NuGet feed. You can create a NuGet feed with a file share or a web-based application. When you have a private PowerShell gallery, you must register the NuGet feed by using the Register-PSRepository cmdlet and specifying the source location. After the repository is registered, users can search it, just like the PowerShell Gallery.

 

Additional reading: For more information about creating a NuGet feed, refer to Hosting your own NuGet feeds.


Saturday, January 18, 2025

Exploring Modules and Commands

Introduction

PowerShell is a powerful task automation and configuration management framework from Microsoft, consisting of a command-line shell and associated scripting language. For beginners, navigating PowerShell's vast landscape of modules, commands, and cmdlets can be overwhelming. This guide aims to simplify the process, providing a starting point for exploration and familiarization with fundamental concepts.

Understanding PowerShell Modules

Modules are self-contained units of PowerShell code that can include cmdlets, providers, functions, aliases, and variables. They provide a way to organize and distribute PowerShell functionality.

Getting Started: Finding and Installing Modules

  1. Find Available Modules: Use the `Get-Module -ListAvailable` cmdlet to see a list of modules already installed on your system.

  2. Install New Modules: Use the `Install-Module` cmdlet to install new modules from the PowerShell Gallery or other sources.

Exploring Module Contents

Once you've found or installed a module, you can explore its contents to see what commands, cmdlets, and other elements it contains.


  1. Get Command: Use the `Get-Command -Module <ModuleName>` cmdlet to see a list of all commands (including cmdlets, functions, and aliases) within a specific module.

  1. Get-Help: Use the `Get-Help <CommandName>` cmdlet to get detailed help and information about a specific command, including its syntax, parameters, and examples.

Example: Exploring the `ActiveDirectory` Module

Let's say you're interested in working with Active Directory using PowerShell. Here's how you might explore the `ActiveDirectory` module:


  1. Check if Installed: Use `Get-Module -ListAvailable | Where-Object {$_.Name -eq 'ActiveDirectory'}` to see if the module is already installed.

  2. Install if Needed: If not installed, use `Install-Module -Name ActiveDirectory` to install it.

  3. List Commands: Use `Get-Command -Module ActiveDirectory` to see a list of all commands within the module.

  4. Get Help for a Command: Use `Get-Help Get-ADUser` (for example) to get detailed help about the `Get-ADUser` cmdlet.

Key PowerShell Concepts

As you explore modules and commands, keep these fundamental PowerShell concepts in mind:


  • Cmdlets: These are the core commands in PowerShell, following a Verb-Noun naming convention (e.g., `Get-ChildItem`, `Set-Location`).  The words “Commands” and “cmdlets” are sometimes used interchangeably, but a cmdlet is a compiled script ready for use in a session (if imported) and a command, is a function call with the Verb-Noun pattern, like “Get-Process”.

  • Objects: PowerShell works with objects, which have properties (characteristics) and methods (actions).  

    • Powershell commands ALWAYS produce objects as output.  Even the use of ‘Out-String’ sends a string object to the console output.  This highlight is critical to understanding what PowerShell does underneath the hood.  You can use the -Verbose command to see what some of the internals are doing, but the concept of returned objects is applied in all cases.

  • Pipelines: You can use the pipe symbol (`|`) to chain cmdlets together, passing the output of one cmdlet as input to the next.  

    • Powershell objects returned by the pipeline are like excel rows and columns.  An object is like a row in the sheet, and each column in the sheet is essentially a property of the object.  By referring to the property names, you can access their contents.  Structured data output, that is, objects, are at the deep core of what Powershell is.

  • Providers: These allow you to access data stores (like the file system, certificates or the registry) as if they were drives.  Since the PSProviders are built-in, we can use the Get-ChildItem, for example, on any of the providers using the -Path parameter as shown:

    • File System:  Get-ChildItem -Path C:\temp\ -Recurse

    • Registry (Current User Hive):  Get-ChildItem -Path HKCU:\Software\

    • Certificates:  Get-ChildItem -Path Cert:\LocalMachine\My 

Conclusion

By exploring PowerShell modules and commands, you can gradually build your understanding of this powerful tool and its capabilities. Remember to use the `Get-Command` and `Get-Help` cmdlets to discover and learn about new cmdlets, and don't be afraid to experiment and try things out.


Installation differences in PowerShell Versions

 

Getting Versioning Clarity

PowerShell and Windows PowerShell are separately installed and you can run supported commands using either environment.

There are two versions of Powershell:

  1. Windows PowerShell - Windows PowerShell is available exclusively for the Windows OS.   All versions of Windows PowerShell up to and including 5.1, which is the version available with Windows 10, are integrated with a Windows OS.

  2. PowerShell - PowerShell is shipped, installed, and configured separately from Windows PowerShell.  First released as PowerShell Core 6.0 in 2018, it was the first version that offered multi-platform support, extending its availability to macOS and Linux operating systems.  However, PowerShell 7 is the defacto for cross-platform scripting in PowerShell with v6 retired.

 

Installation differences in PowerShell Versions

Installing the latest version of PowerShell results in the following when compared to Windows PowerShell:

  • Separate installation path and executable name.

    • Windows PowerShell 5.1 is installed in the $env:WINDIR\System32\WindowsPowerShell\v1.0 location.

    • PowerShell 7 is installed in the $env:ProgramFiles\PowerShell\7 location.  The new location is added to your PATH, which allows you to run both Windows PowerShell 5.1 and PowerShell 7.

    • In Windows PowerShell, the PowerShell executable is named powershell.exe.

    • In version 6 and newer, the executable is named pwsh.exe. The new name makes it easy to support side-by-side execution of both versions.

  • Separate PSModulePath. By default, Windows PowerShell and PowerShell 7 store modules in different locations.  PowerShell 7 combines those locations in the $Env:PSModulePath environment variable.  

    • When you import a module by name, PowerShell checks the location that $Env:PSModulePath specifies.  This feature allows PowerShell 7 to load both Core and Desktop modules.

  • Separate profiles for each version. A PowerShell profile is a script that runs when PowerShell starts.  This script customizes the PowerShell environment by adding commands, aliases, functions, variables, modules, and PowerShell drives.

    • In Windows PowerShell 5.1, the profile's location is $HOME\Documents\WindowsPowerShell.

    • In PowerShell 7, the profile's location is $HOME\Documents\PowerShell.

  • Separate event logs. Windows PowerShell and PowerShell 7 log events to separate Windows event logs (if using a Windows Server or PC).

 

When you're reviewing a PowerShell session, it's important to determine which version you're using.  To determine the current version, enter $PSVersionTable in the PowerShell console, and then select Enter.  PowerShell displays the version numbers for various components, including the main PowerShell version number.

 

PowerShell and Bit-ness

  • On 64-bit operating systems, the PowerShell host applications are available in both 64-bit (x64) and 32-bit (x86) versions.

  • On 32-bit operating systems, PowerShell’s host applications are available only in 32-bit versions.  When working with Windows PowerShell, you'll notice that the icons and window title bars don't have the (x86) designation.  Instead, they display simply as Windows PowerShell and Windows PowerShell ISE in the Start menu.

  • If you intend to use PowerShell to perform administrative tasks on computers that have User Account Control (UAC) enabled, you might have to take an extra step to run PowerShell cmdlets with full administrative credentials.  To do this, right-click or activate the context menu for the application icon, and then select Run as Administrator. When you're running PowerShell with administrative credentials, the host application’s window title bar will include the Administrator prefix