Using ` Microsoft.Extensions.DependencyInjection` in a library
I'm currently writing a wrapper around a REST API and would like to use Microsoft's DI library (normally I just use constructor injection) but I'm a bit confused as to how to do so. I've created a
ServiceCollectionExtensions class and registered the services that I need:
However, I'm not sure what I need to do next. Do I then use this somehow in Program.cs of an example project which uses the library?33 Replies
Unknown User•2mo ago
Message Not Public
Sign In & Join Server To View
I inject the client itself? Or the client given by DI?
Also, what do I pass as
IServiceCollection?Unknown User•2mo ago
Message Not Public
Sign In & Join Server To View
If your code is too long, you can post to https://paste.mod.gg/, save, and copy the link into chat for others to see your shared code!
I'm familiar with it as a concept and how its a solution to the IoC problem. Normally I do ctor injection, ie:
I've used Autofac in the past
Which code?
IAirplanesLiveApi and AirplanesLiveClient?Unknown User•2mo ago
Message Not Public
Sign In & Join Server To View
BlazeBin - wtmwhkaeczmb
A tool for sharing your source code with the world!
BlazeBin - vszuikjazrsc
A tool for sharing your source code with the world!
Unknown User•2mo ago
Message Not Public
Sign In & Join Server To View
into which ctor?
I thought I needed to add IAirplanesLiveApi into the AirplanesLiveClient ctor
as an argument
Right now I just set the value directly in the ctor instead of injecting it, but I'm doing that because I was working off the simple sample that Refit provides
@viceroypenguin I'm also confused because in your example, it seems the BaseAddress is set twice?
https://github.com/viceroypenguin/AlphaVantage.Net/blob/acc24936b7eeb8249a5a9f753f8b03c1c0043346/Source/AlphaVantage.Net/AlphaVantageServiceCollectionExtensions.cs#L86
https://github.com/viceroypenguin/AlphaVantage.Net/blob/acc24936b7eeb8249a5a9f753f8b03c1c0043346/Source/AlphaVantage.Net/AlphaVantageClient.cs#L63
This is what I have so far:
https://github.com/markjamesm/AirplanesLive.NET/tree/main
The project is working at a barebones level (I need to add things like proper type handling, rate limiting, etc), but I'm confused regarding the DI portion
Unknown User•2mo ago
Message Not Public
Sign In & Join Server To View
@Vortac @TeBeCo I wanted
AlphaVantageClient to be a type that could be used without DI as well, so the public AlphaVantage() constructor does not take an IAlphaVantageApi, it creates one from scratch using fixed configuration. This way, one could us the AlphaVantageClient in a linqpad script without having to set up a DI. just pass the api key and a config value and th rest gets handled automaticlly. this constructor should not be called often, but may be desired from time to time.
the other constructor, the internal one, is the one that is called by the DI system, with a refit client that is configured in the servicecollectionextensions file
the reason i do the duality is to cover potential future case where the refit client cannot be consumed directly. i've encountered this before, in cases where certain authntication mechanisms or certain multi-call apis are not really possible via delegatinghandler or some other internal control. so by internalizing the refit client, i have the freedom to change it in the future if necessary, while the public client is concrete and can be consumed directly.
meh, it's actually helpful to me so taht I knwo which specific questions to answer. allowed me to skim the convo quicker. 🙂Testing using just HTTPClient, the responses are returning the correct values instead of 0 with the Refit library
Not sure what was going wrong
can you trim down to a specific case and show both the working httpclient code and the non-working refit code?
The Refit version:
https://github.com/markjamesm/AirplanesLive.NET/tree/main

The main chat channel recommended I switch to plain HTTPClient
So I tried it as a test since I wasn't finding any obvious issues
Refit was returning some of the properties correctly, and some as 0
I took a look at the object in the debugger
i'll take a look in a bit. am distracted atm
No worries
oooooh. you screwed up the models
the
[AliasAs] is only for query parameters and form parameters on things sent to the server as part of the request
the json that comes back runs through STJ, the same as for plain httpclient
so the models need to be annotated with [JsonPropertyName], same as they do in the httpclient version
@Vortacahh
It only affected some properties and not others which is what confused me
there was no explicit error
well keep in mind that STJ automatically translates
camelCase in the json to PascalCase in the C# model for you, so any properties that match in everything except case of the first char will translate automaticallyIs it a big deal to introduce Refit as a dependency in the library? I have both methods working now (Refit and plain HTTPClient) and just want to confirm
i don't think so. i don't have a problem introducing things like refit into my library as a required dependency. it's how i wrote my library. if consumers don't like it, they can write their own.
Thanks for all the help btw, this is much appreciated
there are several schools of thought on transitive dependencies
* some people like to operate with absolutely no transitive dependencies. my library should stand on it's own, with only the bcl as a dependency
* others introduce any dependency they want with no care to what's necessary
* my philosphy is to limit dependencies, but also recognize that my time in building something is precious, so if it makes my life easier in building the library, then i'll add it. if consumers don't like it, they can spend the time writing their own.
in the case of an api client, refit is absolutely a time-saver; the alternative is to use an openapi generator (if an openapi spec is available). most of the time, however, the code provided by such a generator is crap, so refit is my choice.
The only thing I can think of regarding transitive dependencies is that some places need legal to review the code prior to using it, and that includes libraries. But that isn't a concern for this API
which again, falls into the "not my problem" bucket
i don't write something to solve every problem everyone has ever. or to address things for every potential consumer. i write things to make my life easier, and if i can do so in a way that may help others, then i do so. it's up to them to decide if it actually makes their life easier (and legal may be a concern that makes it not easier for them).
but i know that there are companies that don't allow any non-microsoft libraries due to legal. so why would i try to concern myself with that scenario?
i write my stuff MIT license, and i've done interviews with companies before for legal and/or regulatory compliance, so i don't mind working with potential consumers. but i'm not going to concern myself with it unless they come to me with a concern and proposal
because unless they pay me, they don't get to choose how i spend my time, and that includes how i write a library
With API limits of
Am I better off setting rate limits by minutes, or a day?
Currently the API's limit is 1 request/sec but that's changing in a month
so I was initially going to go per minute
1 req/s with no limit
you could do by day, but know that people who run short-form apps (cli, etc.) are going to get absolutely fucked by that
i'd do it by minute or by hour. esp. if it's configurable; if someone knows what they're doing, they can jack it up for a thing they're doing. this also gets into the two ways to configure your lib; one with defaults and one where they provide their own configuration of ihttpclient
I'll go with minute then
So here, you create an
HttpClient:
https://github.com/viceroypenguin/AlphaVantage.Net/blob/acc24936b7eeb8249a5a9f753f8b03c1c0043346/Source/AlphaVantage.Net/AlphaVantageClient.cs#L57
and then in AlphaVantageServiceCollectionExtensions you configure a HttpClient if someone uses DI?
https://github.com/viceroypenguin/AlphaVantage.Net/blob/acc24936b7eeb8249a5a9f753f8b03c1c0043346/Source/AlphaVantage.Net/AlphaVantageServiceCollectionExtensions.cs#L86correct. the
public constructor is for when someone wants to run a quick app, and doesn't want to build a full DI setup to get a single thing to go do a thing. like in a linqpad script
the internal one is the one registered with DI and receive the configured httpclient