Prioritising In a Nutshell
In some past projects, I made the mistake of scheduling important elements for the final project stages. Because of that, we needed to rewrite some integration tests, make additional regression tests and redo other activities that we wouldn’t have to go over if we had done these things earlier.
As a Tech Leader, you ought to know and advise which technical part of the project should be placed at the beginning and which part at the end of the timeline. Due to the fact that in IT we usually have many unclear requirements and many dependencies, this prioritisation is crucial. Well-defined prioritizing can save time which can be wasted on spinning your wheels on unimportant tasks. It also helps to redefine goals in each iteration and focus on what is really important.
The following areas may cause many unexpected issues when they are overlooked. It doesn’t mean these things should be started at the beginning of the project. I want to emphasize the decision-making process regarding these elements. As the old saying goes: Measure twice, cut once.
Bonus: All of the code samples below come from my GitHub repository. You can find a reusable API .NET project template with a full set of functionalities there. You can treat it as a reference project to avoid doing repetitive work or for training purposes.
Logging And Monitoring

A few years ago, I was frustrated when it turned out we didn’t have any log data at the last straightaway of the project. Instead of investigating and resolving the issue, I needed to spend time configuring the tool and collecting data. It is beneficial to collect log data at the beginning of the project. First of all, if your team knows where and how to search log data, they will be more effective in finding issues or explanations as to why something happened in the system. Setting up effective logging and monitoring will drastically decrease the team’s response time in finding and fixing these issues .
In addition, your project probably has some non-functional requirements that have to be fulfilled. Your team can start analyzing and thinking about how to measure those things. Making your logs more descriptive and contextual in each iteration will ensure that you meet expectations at the end of the project without having to scramble.
Tip On How To Get Started
In .NET we have a lot of logging tools like NLog, Log4net or Serilog. However, it usually isn’t enough. If you have a distributed and scalable system you have to use log management. On the market, we can find many complete and useful tools like DataDog or Humio (you can find the full list here). My favourite is Azure Application Insights. The following code presents how to integrate your code with it [GitHub link].
public static IKitbagBuilder AddAppInsights(this IKitbagBuilder builder,
string sectionName = "Logging")
{
if (!builder.TryRegisterKitBag(sectionName))
return builder;
var loggingProperties = builder
.GetSettings<LoggingProperties>(sectionName);
builder.Services.AddSingleton(loggingProperties);
if (!Enum.TryParse<LogLevel>(
loggingProperties?.LogLevel?.Default, true, out var level))
{
level = LogLevel.Information;
}
builder.Services.AddLogging(loggerBuilder =>
{
string? key =
loggingProperties?.ApplicationInsights?.InstrumentationKey;
if (key == null)
throw new
ArgumentException("Instrumentation Key is missing");
loggerBuilder.AddApplicationInsights(key);
loggerBuilder
.AddFilter<ApplicationInsightsLoggerProvider>("", level);
});
builder.Services.AddApplicationInsightsTelemetry();
return builder;
}
Whenever you use ILogger interface and call log methods in your class, log data will automatically transfer to the App Insights. Are you wondering how much it costs? you can find the price list here.
Integration With Other Systems

Have you ever created a bunch of new features one by one for 3 months without any integration attempts, even though you knew it would have to be done one day? I’ve had this unpleasant situation in the past when suddenly, it turns out that internal model was not correct, contracts are not aligned, tests aren’t passed etc. and all because nobody was taking care of the integration part! Your system probably doesn’t exist in a vacuum. Based on my experience, discussing integration should start at the very beginning and continue throughout the entire project. When you start to talk about it sooner rather than later, you can get initial assumptions and start implementing features and establishing business needs at an early stage. As a Tech Leader, be proactive and facilitate these meetings and post follow-up instructions, questions and suggestions.
Tip On How To Get Started
Typically communication between two or more applications can be done using one of the available communication styles. Most popular are Request and Response and Fire and Forget. The code below presents an example from the first option. It shows how you can register custom HttpClient [GitHub link].
public static IKitbagBuilder AddHttpClient(this IKitbagBuilder builder,
string sectionName = "httpClient")
{
if (!builder.TryRegisterKitBag(sectionName))
return builder;
var properties =
builder.GetSettings<HttpClientProperties>(sectionName);
builder.Services.AddSingleton(properties);
builder.Services.AddHttpClient<IHttpClient, KitBagHttpClient>
("kitbag.httpclient");
builder.Services
.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
return builder;
}
It’s always worth to consider applying appropriate patterns like adapter, proxy or facade to each integration point. Additionally, you can start to think about your first contract tests.
Security

What if you left security for last? The consequence of doing that may result in manual tests having to be repeated. I had this situation when we delayed protecting endpoints. Suddenly, we had to align our applications with an external provider and make a necessary modification in infrastructure. Instead of handling security at the beginning, now we needed to take care of it at multiple places at the same time. It disturbed the team and caused unexpected issues at once.
Tip On How To Get Started
The first and easiest step you can do is protect your endpoints. It gives you a good starting point to expand on this topic. If you use Azure Active Directory, you can use the following sample to integrate with it [GitHub link].
public static IKitbagBuilder AddAzureAD(
this IKitbagBuilder builder,
string sectionName = "AzureAD",
string? subsectionName = null)
{
if (!builder.TryRegisterKitBag(sectionName))
return builder;
var section = string.IsNullOrEmpty(subsectionName) ?
sectionName : $"{sectionName}:{subsectionName}";
builder.Services.AddProtectedWebApi(options =>
{
builder.GetSettings(section, options);
options.Events = new JwtBearerEvents();
options.Events.OnAuthenticationFailed = (c) =>
{
if (c.Exception is UnauthorizedAccessException)
c.Fail(c.Exception);
return Task.CompletedTask;
};
options.Events.OnChallenge = (c) =>
{
if (string.IsNullOrEmpty(c.ErrorDescription))
c.ErrorDescription = c.AuthenticateFailure?.Message;
return Task.CompletedTask;
};
}, options =>
{
builder.GetSettings(section, options);
});
return builder;
}
When you use Authorize atribute in controllers, the process of verifying users will work.
Documenting Your Decisions

I imagine that you can have some important reasons to delay doing some of the above things. However, whatever you decide, it is a good habit to document your decisions in a visible location. It can be your confluence page, Wiki page in Azure DevOps or another place you can call Architecture Decision Log (ADL). Those decisions must be made based on your architectural drivers. Let me know in your comments what other things have frustrated you when you had to leave them for last. If you have one that I didn’t mention in this article, please share it in your comments.
Recommended Books:
- Effective Monitoring and Alerting: For Web Operations
- Enterprise Integration Patterns: Designing, Building, and Deploying Messaging
- Design It!: From Programmer to Software Architect
Pick up your next leadership book on Amazon using my affiliate links above to help support my blog.
