|
It's related to the YOLOv5 .NET model.
|
|
|
|
|
|
Thank you, I'll post it there instead.
|
|
|
|
|
Hello guys,
I have an issue related to dependency injection in the Program.cs of a .Net 7 application.
In this case it's an API, but that does not really matter.
Before calling the line:
var app = builder.Build();
I am adding a few singletons normally with :
builder.Services.AddSingleton<IMyConfig, MyConfig>();
builder.Services.AddSingleton<IMyHttpClient, MyHttpClient>();
My issue is that the HTTP client singleton requires info from the config singleton, and it's not a simple case of injecting the former into the latter.
We can't use appsettings.json to manage our configuration, that would be too easy, and because the second one is an HTTP client, I have this code :
builder.Services.AddSingleton<IMyHttpClient, MyHttpClient>();
builder.Services.AddHttpClient<IMyHttpClient, MyHttpClient>(client =>
{
client.BaseAddress = new Uri(myConfig.myURI);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}).ConfigurePrimaryHttpMessageHandler(() =>
{
return new HttpClientHandler()
{
UseDefaultCredentials = true
};
});
.. all this still before I call builder.Build();
I have already googled and chatGPT'd the problem, but the solutions I get are for .Net 6 at best, and do not apply.
My current solution is to use builder.Services.BuildServiceProvider().GetService<imyconfig>() to get an instance of myConfig, but then the builder is called twice, so this instance is lost, and after the builder.Build(), I have to read my config again.
Technically, this works, but it's ugly and triggers my OCD.
If there's any DI god out there, what am I missing ?
Thanks in advance
Fred
modified 28-Apr-23 9:43am.
|
|
|
|
|
If you're "stuck" with a given framework, count yourself lucky if you get something to work. When it does, move on instead of thinking about "ugly"; it's a waste of time.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
If you want a singleton then you have to inject it into a thread flow that does not depend on requests but rather something like the start up method.
But as with the other reply, the point it to deliver something. And you need to have a realistic view about what might actually need to be easily replaced in the future. So does it actually need to be injected. Configuration might be it but you can do that with a standard factory idiom also.
|
|
|
|
|
|
Ok, a few months late admittedly. I'm not a fan of all this functional style boostrapping in ASP.NET core. I find the whole thing obfuscated and difficult to work with and often grapple just to do something simple like config or logging.
Anyway, I have this in my code:
services.AddHttpClient<IMyClient, MyClient>((serviceProvider, httpClient) =>
{
var opts = serviceProvider.GetRequiredService<IOptions<MyHttpOptions>>();
httpClient.BaseAddress = opts.Value.BaseUrl;
})
So, if you just want to get access to config, I think you can just retrieve it from the service provider given as the second parameter to the lambda, no BuildServiceProvider() required.
Regards,
Rob Philpott.
|
|
|
|
|
I'm in the process of building a HTML server using vb.net which dose the job quite well. Currently I'm trying to add a function for downloading files. The sending of plain text works without a glitch (see code 1). However sending files such as executables (*.exe) or Excel (*.xls) files dosen't work (see code 2).
The file once downloaded simply wont run. Upon closer examination (by opening the downloaded file in Notepad) signs of incorrect encoding are typically seen. there are a lot of question mark characters and when compared 1 on 1 with the original file it is clear that the encoding is the problem. Simply said I have no idea on how to resolve this and internet research isn't proving to be a reliable bron of information. Since the problem is one of encoding what I have tried is to read the exe file through a file stream-read and convert its context (probably binary) to text and send that with result that there there is an inprovment but the problem still persists and ultimatlhy the file still dosen't work.
How do I resolve this?
CODE 1
With My404HtmlPage
.Append("HTTP/1.1 200 OK" & Environment.NewLine)
.Append("Content-Type: text/plain & Environment.NewLine)
.Append("Content-Disposition: attachment; filename=" & Chr(34) & "Download.exe" & Chr(34) & Environment.NewLine)
.Append(Environment.NewLine)
.Append("Hello World!")
End With
CODE 2
With My404HtmlPage
.Append("HTTP/1.1 200 OK" & Environment.NewLine)
.Append("Content-Type: application/octet-stream & Environment.NewLine)
.Append("Content-Disposition: attachment; filename=" & Chr(34) & "Download.exe" & Chr(34) & Environment.NewLine)
.Append(Environment.NewLine)
Dim bytes = My.Computer.FileSystem.ReadAllBytes("C:\Original.exe")
Dim MyString As String = Encoding.UTF8.GetString(bytes)
.Append("content-bytes:" & MyString)
End With
|
|
|
|
|
Umm... There is NO encoding for any binary file.
Encoding means "interpet the bytes as this", which will change how the bytes are interpreted, changing them when read. You absolutely do NOT want to change a single byte. You should be just sending the bytes, not creating a string out of them.
|
|
|
|
|
Dim MyString As String = Encoding.UTF8.GetString(bytes)
You just destroyed the content of the file.
Any file that is non-text based is pure binary and should only be read and written as such.
|
|
|
|
|
Bart van Tuijl wrote: Dim MyString As String = Encoding.UTF8.GetString(bytes) No, apply them bytes?
That's what Dave says and he is right. Bytes are that.
No encoding. Write them bytes directly.
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
Okay I get how that should work. I'm not all to sure on how to achieve this and I've given it a shot but it dosn't work as expected all the downloaded file now says when opened in notepad is 77
Here's my attempt.
With My404HtmlPage
.Append("HTTP/1.1 200 OK" & Environment.NewLine)
.Append("Content-Type: application/octet-stream" & Environment.NewLine)
.Append("Content-Disposition: attachment; filename=" & Chr(34) & "Bilandted.exe" & Chr(34) & Environment.NewLine)
.Append(Environment.NewLine)
Dim array() As Byte = File.ReadAllBytes("C:\Test\TestFile.exe")
Using memory As MemoryStream = New MemoryStream(array)
Using reader As BinaryReader = New BinaryReader(memory)
.Append((reader.ReadByte()))
End Using
End Using
End With
Im thinking I need to do something with the byte length but have now landed outside of my field of knowledge?
|
|
|
|
|
What type is your My404HtmlPage variable? Hopefully, it should support writing more than one byte at a time...
If not, you'll need to loop over the bytes and copy them all to the output one by one.
NB: There's no need for the MemoryStream and BinaryReader , since you already have an array of the bytes you need to send.
Dim array() As Byte = File.ReadAllBytes("C:\Test\TestFile.exe")
For i As Integer = 0 To array.Length - 1
.Append(array(i))
Next
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
There is indeed a lot of data now in the downloaded file but its still all in numbers (It dosent look like binary too me but more like decimal without the hyphens) what am I missing here I'm assuming that the browser would know how to handle this data and reproduce a valid file from it (perhaps I'm wrong)?
also to answer the type of variable for My404HtmlPage is
Dim My404HtmlPage As New System.Text.StringBuilder()
which then is passed on to a variable named MyHtmlServerResponse as follows
MyHtmlServerResponse = (My404HtmlPage.ToString)
MyHtmlServerResponse is a string variable as can be seen below
Dim MyHtmlServerResponse As String
EDIT:
Just as extra Info the actual sending is done through TCP/ IP as follows
For Each c As TcpClient In MyClientList
If c Is MyClient Then
Dim nns As NetworkStream = c.GetStream()
nns.Write(Encoding.ASCII.GetBytes(MyHtmlServerResponse), 0, MyHtmlServerResponse.Length)
MyClient.Dispose()
End If
modified 3-Apr-23 12:01pm.
|
|
|
|
|
It does not matter what the content of the file looks like. If you do not understand how to handle binary data without corrupting it then you will never pass go or collect your $200. So stop trying to convdert the content into printable/displayable strings, that just destroys it (as I said in my previous message). You must read and write the content as pure binary bytes, nothing else.
|
|
|
|
|
Bart van Tuijl wrote: also to answer the type of variable for My404HtmlPage is
Dim My404HtmlPage As New System.Text.StringBuilder()
Well, there's your problem. You cannot treat binary data as a string!
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
This My404HtmlPage being a string I had suspected, though Im at a dilemma because my http header information is sent as string and my file as bytes yet they belong to eachother.
Is there a way I can convert my HTTP header to bytes and add my file to it as bytes and then send it or will that not work?
(Sorry guys Im just a hobbyist so my knowledge is limited)
|
|
|
|
|
Yes as I suggested in my other post.
You need to learn what hexadecimal is ('hex').
You need to get a hexadecimal editor (it will be called a hex editor.)
You need to compile a SMALL project and then look at the exe (which is a binary file) using the hex editor. Not notepad.
You need to then look at an image using a hex editor.
You need to then find the specification ('spec') for that type of image and use the hex editor (not notepad) to figure out the parts of the image.
I would also suggest that you write a program parse an image file. NOT display it. Just read it and print out the parts.
1. Read the file with a stream
2. Use the spec to figure out how to read the file.
3. Print out the various pieces. For example there is likely a size (x and y) so print that out as integers.
|
|
|
|
|
Bart van Tuijl wrote: I'm in the process of building a HTML server using vb.ne
Reading through this and your other posts.
You need to come to a full stop on your code and first learn how http and the browser works.
And additionally what a 'binary' file is.
------------------------------------------
Binary file - if is an executable and you open it in notepad will always look like you found. Does not matter where it came from.
Notepad takes data and then transforms it in to characters.
That can only work if the data is in fact characters.
A binary, especially an executable will never consist solely of characters. So of course notepad will never display it because it cannot. Notepad displays a '?' for data that is not actually characters.
Some (most) executables will have data in them that you will be able to read. Doesn't mean the rest is wrong just that an executable has text in it.
And all of that depends on what character set notepad expects to see (I suspect you might want to research that also.)
You can experiment with this by using notepad to open various files on your computer. I suggest
1. Executable
2. Image file
3. Write your own program, put text in it (a string), compile it, then open that.
Do NOT save anything in Notepad to those above files. Unless you want to destroy them (try it if you wish but only if you expect to lose it.)
If you really want to modify a binary file manually then you need to find a 'hex editor'.
If you want to do that then you will need to learn what 'hex' means.
------------------------------------------
A browser sends a request to a web server and the web server then responds to that request.
You should learn about the HTTP protocol.
Your browser will have a 'developer tool' which allows you to inspect both requests and responses.
The HTTP protocol itself does not support file downloads in anyway.
A specific request might result in some content which originates from files being downloaded.
1. A html response (from a request) might have tags in it which the browser which will then use to make another request to the web server, and the response body with have data which is an image. The request defines this not the HTTP protocol.
Browsers used to support a 'ftp' protocol that allowed files to be downloaded. Rather than 'http' it started with 'ftp'
However apparently newer versions (Chrome, Firefox) no longer support that at all. So you would need to get an older version if you wanted to implement that protocol.
|
|
|
|
|
So, I've done mainly VBc and C/C++ for embedded device, and a tiny bit of VC++. When .Net came along, after a while, it was often repeated that .Net allowed people to write bad code, but will still work. I was a stickler for following good programming form.
On one occasion, someone had ask a question about what the .Net compiler will do with [whatever code it was], and someone else chimed in saying something else like 'the compiler is smart and will optimize...'.
But, you know, I'm still a stickler for proper form, allocating vars and objects, properly destroying them, stopping any timers before program exit, etc. I guess, proper "cleanup" you could say.
So I'm working with some code the company hired a supposedly experienced programmer to write a program for the company that monitors devices it makes. Some of this is so appalling, that it looks like an absolute beginner would write. So the below chunk of code is one function he had written. He has this running in it's own thread, and it's a UPD listening socket. This is used to prevent multiple instances of it running, and to return from the system tray after it's been minimized to the tray. So this function is always running in it's own thread...
Private Sub udpThreadsub()
While True
Try
udpcl = New UdpClient(UDPPORT)
Dim RemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
While True
Try
Dim rec = udpcl.Receive(RemoteIpEndPoint)
If rec.Length = 11 Then
Dim match = True
For i = 0 To 10
If rec(i) <> UDP_MSG(i) Then
match = False
Exit For
End If
Next
If match Then
Outoftray()
End If
End If
Catch e As Exception
End Try
End While
Catch e As Exception
End Try
End While
End Sub
To me, this is some of the ugliest code I've ever seen. I mean, the compiler isn't THAT smart is it?
To me, this looks like the dim'd object will be created and sent to GC every iteration through the loop! But then again, I don't have an intimate knowledge of what the compiler will do with this. Will it just realize that it should just reusing these objects and not instantiate them and send GC as it appears they would?
I would have done the DIM's above the loops, and then reuse them in the code.
So is this some of the worse code ever seen (by me anyway) or is the compiler just 'that smart'?
Thanks in advance.
|
|
|
|
|
Ignoring the fact that this is VB.NET ...
The outer loop only runs if an exception is thrown (and swallowed) outside of the inner loop's exception-swallowing Try..Catch block. Realistically, the only things that could trigger that would be the creation of the UdpClient , or the creation of the IPEndPoint . But that would mean that either the port was inaccessible, or the application had run out of memory. In which case, the next iteration would almost certainly throw the same exception again, leading to a thread constantly executing a tight try-throw-catch-try-again loop.
The receive call will allocate a new byte array. But there's no option to avoid that, and no way to make it reuse the same array. The only way that could be optimized would be if the BCL code did it for you. But that's unlikely, since it has no way of knowing what the caller will do with the returned array. So you'll have some GC churn on the inner loop.
If this is intended to implement a single instance application, there are far better ways to do that. For a start, in a VB.NET WinForms project, there's a specific option on the application properties to do this.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Without a (stopwatch) timing, the "GC collecting" theory is meaningless.
I'm amazed how fast C# can run "before" I've bothered with my optimizations; where I routinely create objects in called methods that run at many frames per second. I had the same concerns and found I had cycles to spare.
The GC "graph" just chugs along.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
I've seen uglier code than that, but there is still only so much the compiler can do with what it sees. Detection of "code intent" is what gives a compiler the ability to optimize, but it can only go so far. The compiler can optimize inside methods, but over large sections of an app or even a class? Not so much.
The compiler cannot optimize you out of bad design.
|
|
|
|
|
Member 10097972 wrote: VBc and C/C++ for embedded device, and a tiny bit of VC++.
Perhaps the rest of the comments are based on that background.
Certainly for me (decades ago) working on computers with much smaller memories one had to be much, much more careful not only with how memory was used but how and when it was allocated.
Computers have substantially more memory than almost all embedded devices. That was even true long ago. Both have gotten bigger since then.
Additionally for PC computers the OS and compilers/interpreters have been designed for decades to optimize the usage of that memory.
One need only read up on how memory heaps used to work (perhaps even how they are still taught) versus the complexity that goes into moderns heaps to see the changes. And even reading up on how the OS and even the CPUs are optimized to assist in that. Even physical memory and other hardware in computers has changed to facilitate that.
Member 10097972 wrote: So this function is always running in it's own thread...
Excluding the VB part of that...
Yep that is how you write it - in its own thread. Unclear to me why you seem to think that is a problem?
Member 10097972 wrote: This is used to prevent multiple instances of it running,
Not sure what that is supposed to mean. But any IP port should never have more than one reader. Not in any circumstance. So mentioning seems odd since that is exactly what must happen.
Member 10097972 wrote: the compiler isn't THAT smart is it?...I would have done the DIM's above the loops
I think this is your major concern.
And yes the compiler (and interpreter in this case) is that smart.
The code I see is getting a message, in a buffer, but still a message. So the API creates the buffer and not the code that you posted. You definitely could not have moved that outside the loop. (As mentioned compiler/interpreter will easily deal with this.)
So I don't see any other allocations in the loop?
|
|
|
|