You might not need to use multi-threading in all of your C# applications but as a modern software developer, you should make this part of your toolkit.
- Wikipedia best explains what thread is. It also explains the difference between threads and processes and delves into the topic of multi-threading as well, which is what thread is for.
- Benefits of using multi-threading:
- To maintain a responsive user interface.
- To perform CPU bound work while waiting for I/O operations to complete.
- To scale the application using parallel execution.
- Price to pay for using multi-threading:
- Slower execution time on single-processor machines due to context switching.
- Added program complexity.
- Threading (C#) at Microsoft docs describes the basic concurrency and synchronization mechanisms provided by the .NET Framework, but not much example C# code though.
- Threading in C# by Joseph Albahari is a good one as it provides example C# code. It goes through the basics of threading and synchronization in C# which would help you get started writing C# code. Then it talks about the event-based asynchronous pattern (EAP) and lastly about parallel programming.
- C# Programming Examples on Threads is the simplest C# codes I found on C# threading.
- Microsoft recommends using the task-based asynchronous pattern (TAP) though. The async and await keywords in C# support TAP. So I think it would be best to focus on this instead of the older patterns like the event-based asynchronous pattern (EAP) and the asynchronous programming model (APM).
- Parallel Processing and Concurrency in the .NET Framework in Microsoft docs contains links to information about threading, asynchronous programming patterns (both legacies and new) and parallel programming.
- For parallel programming, the Task Parallel Library (TPL) is the center of it all and would be wise to get familiar on this library.
A while back, I delved into Android development using Android Studio and Java (in this article). It was a little bit difficult for me as I need to familiarize myself with Android Studio and relearn Java. But with Xamarin now part of Visual Studio, it became easier. All I need to concern myself is the Android development itself. So in just a few days, I created my first usable Android mobile application. This app can now receive SMS messages but the sending of HTTP messages is still in the works (which is why it’s still in a preview).
Anyways, what did I do to make this SMS work? The app registers a broadcast receiver for SMS messages. This broadcast receiver then sends an ordered broadcast to the app where it has 2 more broadcast receivers: one broadcast receiver to update the UI with the SMS message received when the app is running, and another one to display a notification when the app is not running. When the notification is clicked, the app will launch and the chat will start.
I see a potential in this mobile development space for me, and for this app which I will continually build on. There are still a lot of work in progress here. One takeaway for me on this is that Xamarin does really help you develop Android apps using your favorite language C# and your favorite IDE Visual Studio.
Resources and Tools:
DIP (or Dependency Inversion Principle) is one of the principles of SOLID. SOLID stands for:
- Single responsibility – a class should only have one responsibility
- Open / closed principle – a class should be open for extension but closed for modification
- Liskov substitution principle – a class should be replaceable without altering the functionality of the whole
- Interface segregation principle – better to have more specific interfaces than a general purpose one
- Dependency inversion principle – a higher-level class should never depend on a lower-level class, instead higher-level class should define an abstraction that lower-level class should depend on
IoC (or Inversion of Control) is a paradigm that adheres to the dependency inversion principle by inverting the control to avoid dependencies. Most inversions can be generalized into these three types of control:
- Control over interface – consumer class should have control over the interface and provider classes should depend on that interface
- Control over flow – a “don’t call us, we’ll call you” paradigm
- Control over creation – where creating objects is done outside of the class they are being used in
DI (or Dependency Injection) is one way of inverting control over creation (other ways being the factory method and the service locator). It moves the creation and binding of a dependency outside of the class that depends on it. Common types of dependency injection:
- Constructor injection
- Setter injection
- Interface injection
ASP.NET MVC 5 Framework does not limit you to the capabilities it provide out of the box. It is an extensible framework which emphasizes on convention over configuration or coding by convention, and below are some ways you can extend it.
- Action Results
- Action results are returned by the controller (e.g. return View()).
- They are responsible for writing response to a request.
- They are executed internally by MVC to write out the response.
- You can create a custom action result by inheriting from ActionResult and overriding ExecuteResult(), or by extending an existing action result (e.g. FileResult).
- Action Filters
- Action filters execute before and after a controller action method.
- You can create a custom action filter by implementing ActionFilter‘s OnActionExecuting() and OnActionExecuted() methods.
- They can be applied at the method, controller, or global scope.
- Helper Methods
- Two types: inline Razor helpers (@helper) and HTML helpers (@Html.*).
- They reduce code duplication but if it involves complex logic consider using partial view / child action method.
- You can create your own HTML helper by creating an extension method to HTMLHelper.
- View Engines
- When controller returns a view, the MVC executes the action result and in the process uses a view engine to find a view and returns a ViewEngineResult whose Render() method is called.
- A custom view engine can be used to extend view selection functionality such as to implement swappable UI themes (e.g. WordPress themes).
- You create a custom view engine by extending the RazorViewEngine and in the constructor setting the search location format properties to use the theme directories that you want the view engine to search for for the currently active theme.
- You register the custom view engine in Application_Start() calling ViewEngines.Engines.Insert(), inserting it as the first engine to be evaluated. You can leave the RazorViewEngine there if you want a fallback. Note that MVC supports multiple view engines.
- Exception Filters
- Exception filters catch errors that occur inside the scope of action method execution (including inside action filters and action results) and thus provide more contextual framework information.
- The default exception filter in MVC is the HandleErrorAttribute.
- You can create a custom exception filter by implementing the IExceptionFilter‘s OnException().
- They can be applied at the method, controller, or global scope.
- The ExceptionHandled flag is useful when using multiple exception filters: checking to make sure exception was not handled by previous exception filter before continuing.
- Application_Error() should still be implemented as a fallback.
- Server-Side Validations
- Two ways: via data attributes (e.g. Required, Range, etc.) and implementation of IValidatableObject‘s Validate() in the model class, the former being reusable while the latter providing easy cross property validation.
- The model binder that binds the request data to the model classes (or the action method parameters) checks the data attributes first then the Validate() and populates the controller’s ModelState property which you can check if any errors occurred in the model binding process (e.g. ModelState.IsValid).
- You can create a custom data attribute by inheriting from ValidationAttribute and overriding IsValid() and setting the ErrorMessage in the constructor.
- You can implement the IValidatableObject‘s Validate() in the model class and return List containing any error messages.
- Model Binders
- A model binder implements the IModelBinder‘s BindModel(). The binder model is returned by a model binder provider that implements IModelBinderProvider‘s GetBinder(). The model binding process searches through a list of model binder providers asking them if they can provide a model binder for the data it is trying to bind.
- You can create a custom model binder by implementing IModelBinder‘s BindModel() and adding any error messages to the controller’s ModelState. Then you create a custom model binder provider by implementing IModelBinderProvider‘s GetBinder() to return the custom model binder you just created. You register your custom model binder provider in Application_Start() by calling ModelBinderProviders.BinderProviders.Insert().
- Value Providers
- A model binder employs value providers to provide it data from different sources such as posted form data, query string, route data, etc. that it can use to populate the action method parameters.
- Possible uses of a custom value provider is to provide HTTP header data or settings from configuration file or database.
- You create a custom value provider by implementing IValueProvider‘s two methods: ContainsPrefix() to return true if the passed in property name matches any data the custom value provider provides and GetValue() to return the value itself. Then you create a custom value provider factory by inheriting from ValueProviderFactory and overriding GetValueProvider() to return the custom value provider you just created. You register your custom value provider factory in Application_Start() by calling ValueProviderFactories.Factories.Insert().
- Authentication Filters and Authorization Filters
- Authentication filters implement IAuthenticationFilter‘s two methods: OnAuthentication() to authenticate a request and OnAuthenticationChallenge() that runs when authentication fails and right after action method execution.
- Authorization filters implement IAuthorizationFilter‘s OnAuthorization().
- These filters return a non-null context results if authentication/authorization fails.
- Note that MVC supports Forms and Windows authentication by default and does not support Basic authentication. One use of a custom authentication filter is to provide Basic authentication.
- You create a custom authentication filter by implementing IAuthenticationFilter. For custom authorization filter, consider inheriting from AuthorizeAttribute instead.
- Action Name Selectors and Action Method Selectors
- Action name selectors (e.g. [ActionName(“xxxxx”)]) and action method selectors (e.g. [HttpGet] and [HttpPost]) influence the decision process of selecting which action method to handle the request by the action invoker.
- You can create a custom action name selector by inheriting from ActionNameSelectorAttribute and overriding IsValidName().
- You can create a custom action method selector by inheriting from ActionMethodSelectorAttribute and overriding IsValidForRequest().
BONUS: Found this good article worth looking too: 10 ways to extend your Razor views in ASP.NET core – the complete overview.