Esa
Esa
CC#
Created by Esa on 6/14/2024 in #help
dotnet publish fails due to a build error that doesn't happen when I run just dotnet build
Hi there, I'm having a weird thing going on here. I use Jetbrains Rider, and have a project that uses a class library a colleague made. The error that is happening says that Required member X.Y must be set in the object initializer or attribute constructor. And this is super weird to see as an Error and not a warning, because 1) we never instantiate that class, it's resolved through DI and 2) this works in a regular build. So it's only during the publish part this goes wrong. I don't even know where to begin troubleshooting this. Any advice?
18 replies
CC#
Created by Esa on 6/3/2024 in #help
Need help debugging a tiny console app on server
Halp. I'm losing my mind rapidly. Scenario: I'm writing a tcp client tester to PoC something, and I've written it as a tiny console application where I use dependency injection to see that that aspect also works.
services.AddOptions<SysConfig>()
.Configure<IConfiguration>((options, configuration) => configuration.Bind(SysConfig.SectionName, options))
.Validate(options => options.Port is not default(int), $"{nameof(SysConfig.Port)} is not defined!")
services.AddOptions<SysConfig>()
.Configure<IConfiguration>((options, configuration) => configuration.Bind(SysConfig.SectionName, options))
.Validate(options => options.Port is not default(int), $"{nameof(SysConfig.Port)} is not defined!")
This is how I normally do it. However... When I run this exe on the target server, it fails on the Validation step. It says the values are default. And this is where it gets weird. If I replace that neat configuration oneliner with an explicit behemoth that manually gets the required section, retrieves the string and binds it to the property - then it works:
.Configure<IConfiguration>((options, configuration) =>
{
IConfigurationSection sysSection = configuration.GetRequiredSection("Sys");
if (!sysSection.Exists()) throw new Exception("Missing section \"Sys\" in configuration!");

var portAsString = sysSection.GetValue<string>("Port");

options.Port = int.Parse(portAsString!);
})
.Configure<IConfiguration>((options, configuration) =>
{
IConfigurationSection sysSection = configuration.GetRequiredSection("Sys");
if (!sysSection.Exists()) throw new Exception("Missing section \"Sys\" in configuration!");

var portAsString = sysSection.GetValue<string>("Port");

options.Port = int.Parse(portAsString!);
})
But attempting to oneline it causes the error where everything is default, and thus failing validation. This only happens on the target server which has a .net 8.0 x64 runtime installed, whereas I have a .net 8.0 x64 SDK installed on my dev environment. Does this make sense to anyone? I don't really know where to start looking, apart from installing an SDK on the server to see - but that sounds very wrong lol.
41 replies
CC#
Created by Esa on 3/13/2024 in #help
HttpContext and TraceIdentifier
Anybody familiar with how the TraceId of HttpContext works? I am aware it represents a {TraceIdentifier}:{Span} format with the former being the overall identifier of an Activity and the latter being a specific sub-operation performed in the context of that activity. But I don't understand when one activity starts and another one stops. I tried performing multiple repeat API requests through swagger, and they all got the same TraceIdentifier but incrementing Spans. Can anyone clarify what is happening? I have a common .net 8.0 setup of program.cs for a WebAPI solution.
5 replies
CC#
Created by Esa on 2/25/2024 in #help
GIthub Actions - struggling with finding any example
Hi! I want to try out github actions, but I'm honestly not finding any .net example of hello world published. Have any of you guys done it before?
2 replies
CC#
Created by Esa on 1/18/2024 in #help
BinarySerialization - need some design help
Hi, this is my first foray into lower level programming and I could use some help. I am writing a DOCSIS-compliant binary serializer for C#. It will take as input a .cfg or .txt file that resembles a JSON, but is a bit different:
Main
{
DownstreamFrequency 130000000;
UpstreamChannelId 123;
NetworkAccess 1;
ClassOfService
{
ClassID 5;
MaxRateDown 512000;
MaxRateUp 64000;
PriorityUp 3;
GuaranteedUp 32000;
MaxBurstUp 54314;
PrivacyEnable 1;
}
MaxCPE 13;
SwUpgradeServer 10.1.1.1;
/* CmMic e241803a16fa62269f90d6e1619a59d3; */
/* CmtsMic 41141948116bcc38f6a20ec485fcd0f2; */
/*EndOfDataMkr*/
}
Main
{
DownstreamFrequency 130000000;
UpstreamChannelId 123;
NetworkAccess 1;
ClassOfService
{
ClassID 5;
MaxRateDown 512000;
MaxRateUp 64000;
PriorityUp 3;
GuaranteedUp 32000;
MaxBurstUp 54314;
PrivacyEnable 1;
}
MaxCPE 13;
SwUpgradeServer 10.1.1.1;
/* CmMic e241803a16fa62269f90d6e1619a59d3; */
/* CmtsMic 41141948116bcc38f6a20ec485fcd0f2; */
/*EndOfDataMkr*/
}
This is a barebones, minified example of what these files will contain. Every line is either a property or a collection of properties. I will refer to these properties as DocsisProperty<T>, since they will be deserialized into a C# type and then encoded into byte[] later on. Now the issue I am facing is that there are 25 ish encoding methods and 25 decoding methods, but hundreds of different properties. All unique properties are stored in a property map with name, id and a reference to the correct method for encoding or decoding. This can be seen here: https://github.com/rlaager/docsis/blob/master/src/docsis_symtable.h My original idea was that when I am parsing a file, I can initialize a new DocsisProperty<T> based on the identifier of the value, then later on when I want to encode it I call docsisProperty.Encode(), and it will look up some static dictionary to figure out which encoding method is the appropriate one. However that gets complicated quickly because of the generic type on DocsisProperty<T>. The dictionary would then have to use object or dynamic as it's return type, and I am not a fan of either approach.
57 replies
CC#
Created by Esa on 11/16/2023 in #help
✅ class library and exposing a type from another namespace
Hi, in my company we have an underlying core application which runs things. This application has many modules (.dlls) which have apis we can call. So we usually reference those binaries in our solutions. However the way this is done currently is by downloading the binaries from an internal repository and referencing them in our solutions. I'd like to move this entire process to our private nuget, so that we never have to touch a binary manually again. So currently I've setup a release pipeline to that private nuget source. Consider the following modules:
CoreApp.Customers.dll
- ICustomersService.cs
CoreApp.Products.dll
- IProductsService.cs
CoreApp.Customers.dll
- ICustomersService.cs
CoreApp.Products.dll
- IProductsService.cs
I have created a class library solution that mirrors this somewhat:
Internal.CoreApp
Customers
Products
Internal.CoreApp
Customers
Products
So what I want to achieve is that a developer that needs ICustomersService in their solution can install my nuget package in their solution, and use my extension methods on IServiceCollection to add ICustomersService to the DI in their .net 7.0 project. And it works so far. However, when I'm testing this from a different project that has installed my nuget package, I don't have access to the type ICustomersService. I think that is because it doesn't come from the same namespace and is hidden behind my abstraction layer, so how can I expose this?
2 replies
CC#
Created by Esa on 11/14/2023 in #help
Need help structuring a class library for internal tools
Hi there, I'm working on creating an internal tool for exposing some commonly used functionality that requires external binaries. So we have a business critical core application that consists of many modules. These modules all have their own APIs available through .dll files. Assume Customers.dll, Finance.dll, Products.dll and so on. Each one of these have IProductService and IProductConfigurationService for example. When we create solutions, tools or integrations we often use some subselection of these modules, but rarely all. Currently we bake this into the solutions by moving the relevant binaries we'll be using into the repository so that it'll be available to the CI / CD pipelines. But ideally I'd want to have this as a nuget package from our private nuget repo instead. So instead of finding the binaries we need and physically move them into our repo, I'd prefer something like nuget install OurCoreApp.Customers, nuget install OurCoreApp.Products and for that to add the required binaries. That means we only have to update binaries in one place (the OurCoreApp solution that we use as a nuget package). However I've never really done this before. I assume this means I'll create a class library called OurCoreApp, but how do I make the different modules available as separate nuget packages?
3 replies
CC#
Created by Esa on 10/6/2023 in #help
✅ Help with authentication/authorization for my application with .net 7
Hi, I was hoping someone could help me out with Claims/Identity/Roles. I have an application with a couple system users. These users pass an API Key along their requests. Through this api key, I find their actual user in a DB. In addition to the User table, I have a Feature table and a UserFeature table that connects a user with some feature of the application. This is how I can see that userA has access to the feature CustomerSearch for example. I would like to move away from gnarly if-checks in the controller to see if a UserFeature entity exists with the userId, and instead make use of the annotations found in .net on the controller endpoints so that I can simply annotate that a method requires a certain feature. Any ideas?
39 replies
CC#
Created by Esa on 9/21/2023 in #help
❔ Locking of serialized inventory
Hi, me and a colleague are discussing the topic of locking. In my mind locking is just a simple means to an end that shouldn't require much magic. Our usecase is that we have a database of entities with serial numbers. We support read/write operations on these, but whenever one entity receives a write operation we want to lock that entity until the write operation is done in a way that blocks concurrent write operations for specifically only that entity but no other entities. We also use async/await a fair bit, so we cannot perform our logic inside a lock-block. So I opted for a ConcurrentDictionary<string, SemaphoreSlim> where string is the key we use to lookup the entries, and a semaphoreslim blocks access with its timeout set superlow (1 nanosec). This is obviously a hack and my suggestion doesn't feel right. But adding a full lock-class also feels overkill and like we're missing something obvious. Behold my hacky suggestion:
private readonly ConcurrentDictionary<string, SemaphoreSlim> entityLocks = new();

SemaphoreSlim semaphore = entityLocks.GetOrAdd(entity.Id, new SemaphoreSlim(1));
await semaphore.WaitAsync(TimeSpan.FromMilliseconds(config.LockTimeoutMilliseconds)).ConfigureAwait(false);

try
{
// do stuff
}
finally
{
semaphore.Release();
entityLocks.TryRemove(entity.Id, out _);
}
private readonly ConcurrentDictionary<string, SemaphoreSlim> entityLocks = new();

SemaphoreSlim semaphore = entityLocks.GetOrAdd(entity.Id, new SemaphoreSlim(1));
await semaphore.WaitAsync(TimeSpan.FromMilliseconds(config.LockTimeoutMilliseconds)).ConfigureAwait(false);

try
{
// do stuff
}
finally
{
semaphore.Release();
entityLocks.TryRemove(entity.Id, out _);
}
Any thoughts?
2 replies
CC#
Created by Esa on 8/14/2023 in #help
❔ ✅ Schrödinger's errors (errors in build but not compile)
7 replies
CC#
Created by Esa on 3/29/2023 in #help
yield???
public IEnumerable<int> A()
{
for (int i = 0; i <= 10; i += 2)
yield return i;
}



public IEnumerable<int> B()
{
var ints = new List<int>();
for (int i = 0; i <= 10; i += 2)
ints.Add(i);

return ints;
}
public IEnumerable<int> A()
{
for (int i = 0; i <= 10; i += 2)
yield return i;
}



public IEnumerable<int> B()
{
var ints = new List<int>();
for (int i = 0; i <= 10; i += 2)
ints.Add(i);

return ints;
}
What is the difference here?
22 replies
CC#
Created by Esa on 3/9/2023 in #help
❔ How to handle longrunning tasks and cancellation in asp.net core?
Hi, one of the applications we have at work has a long-running background task. The application is an older fx472 app where we just have a public static Task LongRunningTask; and public static CancellationTokenSource source;, and these are defined in global.asax.cs which i'm now trying to migrate to Startup.cs instead. This task is not dependent on user input and just silently runs every hour. How does one usually handle long-running tasks that may need to be cancelled in asp.net core (.net 7.0)?
12 replies
CC#
Created by Esa on 12/8/2022 in #help
❔ Mocking with EntityFrameworkCore
Hm, I'm creating unit tests for a class that has a private readonly MyDbContext dbContext; that causes a few problems.
InternalDbSet<MyEntity> invocation failed with mock behavior Strict.
All invocations on the mock must have a corresponding setup.
InternalDbSet<MyEntity> invocation failed with mock behavior Strict.
All invocations on the mock must have a corresponding setup.
And you can't really mock that as you would everything else, because you cannot instantiate any DbSet collections as they don't have a non-private constructor. Anybody who has mocked stuff with DbContexts on them? I'm not sure how to approach this.
4 replies
CC#
Created by Esa on 12/7/2022 in #help
❔ Need help with a LINQ query
Hi, I could use a bit of help building a LINQ query. Assume a simple entity like this:
Event
int EventTypeId
int CustomerId
Event
int EventTypeId
int CustomerId
Then you have an IEnumerable<Event>. From this collection I want to extract all customer ids that only have eventTypeId == 1 associated with them. So if there are two events for one customerId, and those two eventTypeIds are 1 and 2 then I don't want that associated customer id. If both eventTypeIds are 1 then I want that specific customerId. Does that make sense? Currently I have this
from event in events
group event by event.CustomerId
into customerEvents
where customerEvents.All(event => event.EventTypeId != 2)
select customerEvents
from event in events
group event by event.CustomerId
into customerEvents
where customerEvents.All(event => event.EventTypeId != 2)
select customerEvents
But looking at it it doesn't really make sense. And it doesn't return what I thought it would. Any ideas?
21 replies
CC#
Created by Esa on 11/28/2022 in #help
❔ EntityFramework async where possible?
So I want to make sure I don't do something stupid here. I'm trying to convert my DbContext-calls to async calls where possible. I see EF provides .FirstOrDefaultAsync() which works nicely for the Get calls I have. However I need to do stuff like join and where which I see has no async overload. I started doing
Task.Run(async () => await myDbContext.MyDbSet.Join() // etc
Task.Run(async () => await myDbContext.MyDbSet.Join() // etc
but that feels wrong. How do I make this particular call async without doing something explosively stupid?
23 replies
CC#
Created by Esa on 11/11/2022 in #help
❔ Help with designing a functional container object
Hi, I could use some input for a functional container/result object I'm working on. I want it (the struct itself) to never be able to be null or contain null, but this is a situation I'm not quite sure how to handle. It's meant to return the result of invoking a function, but some functions will evaluate to null and I'm not sure how to model that. 🤔 I know that functions that directly accept a T value can throw an exception if that is null as it can be seen in compiletime, but in this case I'm not quite sure what should happen as I cannot check a Func for null until it is actually ran and then it is too late.
public readonly struct Outcome<T> {
private readonly T value;
private readonly string errorMessage
public readonly bool IsSuccess

public static Outcome<T> Of(Func<T> function)
{
if (function == null)
throw new ArgumentNullException(nameof(function));

try
{
var value = function();

if (value == null)
return value == null ? Error("Value cannot be null!") : Success(value);
// throw new ValueIsNullException("Value cannot be null!");

return Success(value);
}
catch (Exception exception)
{
return Error(exception);
}
}
public readonly struct Outcome<T> {
private readonly T value;
private readonly string errorMessage
public readonly bool IsSuccess

public static Outcome<T> Of(Func<T> function)
{
if (function == null)
throw new ArgumentNullException(nameof(function));

try
{
var value = function();

if (value == null)
return value == null ? Error("Value cannot be null!") : Success(value);
// throw new ValueIsNullException("Value cannot be null!");

return Success(value);
}
catch (Exception exception)
{
return Error(exception);
}
}
3 replies
CC#
Created by Esa on 8/22/2022 in #help
How can I inject methodname into ILogger.Debug()-call without changing useage everywhere?
Hi, I have some property I wish to inject into my log messages (Serilog). I found a way to obtain it, but it requires a new method:
public static void Debug(this ILogger logger,
string logMessage,
[CallerMemberName] string memberName = "",
params object[] propertyValues)
{
using (LogContext.PushProperty("MethodName", memberName))
logger?.Debug(logMessage, propertyValues.ToArray());
}
public static void Debug(this ILogger logger,
string logMessage,
[CallerMemberName] string memberName = "",
params object[] propertyValues)
{
using (LogContext.PushProperty("MethodName", memberName))
logger?.Debug(logMessage, propertyValues.ToArray());
}
The idea here is that I can enrich the log template with the method name of the callsite. But this isn't the same Debug method found in the ILogger interface - so I'll have to use this method instead of that one. Is there a better way to achieve the same without using this method (since I'll have to add a using statement to use it)?
2 replies