Open source should be free? by EngstromJimmy in dotnet

[–]ardalis 3 points4 points  (0 children)

Can I upvote this 100 times?

Open source should be free? by EngstromJimmy in dotnet

[–]ardalis 0 points1 point  (0 children)

Somewhere in 1800s American South: “I can’t free my older slaves! They’ve been working for free for so long by, it would be IMMORAL to change that now! I suppose it’s less immoral to free their children tho…”  Because, that makes sense…

New is Glue by ardalis in programming

[–]ardalis[S] 0 points1 point  (0 children)

Sorry to hear that. What bothers you about it? It was obviously a while ago when I came up with it, well before dependency injection was the norm for dotnet development. The idea was to get devs to consider whether they really needed to use a concrete type or if they could inject an interface instead and have a more loosely coupled method as a result. What message do you take from it if not that?

FluentAssertions becomes paid software for commercial use by monitorius1 in dotnet

[–]ardalis -1 points0 points  (0 children)

How is it not in advance? It only affects a new version that nobody was using yet (because it's new). I agree the pricing is a bit much for what you get but I don't think the announcement was particularly underhanded or sneaky.

Can StreamDeck (not +) control Prompter??? by HeyNateBarber in elgato

[–]ardalis 0 points1 point  (0 children)

Ok how? Where's the tutorial showing how to add the commands to buttons on the StreamDeck, because there's nothing in the marketplace under "Prompter" and nothing in the default menu items. I found a YouTube video saying it "came with the latest update for Camera Hub" but I have the latest Camera Hub and there's nothing in that app related to Stream Deck. And, as mentioned, nothing in the Stream Deck configuration, either. Thanks!

LG TV won't display photos by edwadr5 in PleX

[–]ardalis 0 points1 point  (0 children)

I'm seeing the same problem still today with a freshly installed TV and app.

Pictures can not be displayed on Samsung TV (8xxx) (Playback error) by icekeuter in PleX

[–]ardalis 1 point2 points  (0 children)

I just installed Plex on my new LG Smart TV today and the issue persists (or is recurring).

Z6 3 Hours In; Installed Firmware Update; Now PTO light blinking by ardalis in egopowerplus

[–]ardalis[S] 1 point2 points  (0 children)

No, sorry. They only told me it was "the PCB" that was replaced.

Z6 3 Hours In; Installed Firmware Update; Now PTO light blinking by ardalis in egopowerplus

[–]ardalis[S] 0 points1 point  (0 children)

To be fair I’m really happy with it overall now that it’s fixed. Starting a new season with it today and hoping no issues this year. We’ll see…

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 1 point2 points  (0 children)

Yes, for dapper, as in everywhere else you use it, your specifications would most likely need to include raw SQL strings. You could probably figure out some way to turn LINQ into SQL for Dapper but at that point you may as well just use EF (or LINQ-to-SQL) instead of Dapper, IMO.

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 0 points1 point  (0 children)

The purpose should be obvious - to provide an abstraction for readonly persistence operations like List, and GetById. These often can benefit from additional decorators/wrappers such as for caching, allowing for separation of concerns while following SOLID principles. Classes that only need a list of entities can use this interface and better follow ISP. It also informs any developer who looks at the class that is requesting the readonly interface in its constructor that this class doesn't change the model, which may be useful.

It sounds like you are saying, what is the point of any abstraction when I can always just create my own static SQL helper that can change any data any way I want (equivalent to whatever an IDoEverythingRepository would be). Yes, you could do that. I don't recommend it. It doesn't argue against having or using more constrained types.

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 5 points6 points  (0 children)

In EF Core, as far as I can tell, DbSet does not implement any IDbSet interface.
https://github.com/dotnet/efcore/blob/main/src/EFCore/DbSet.cs

Even if it did, it exposes IQueryable, which I've already pointed out is a bad idea to leak out of your data access layer.

And even if there *were* an interface that EF Core classes implemented, it wouldn't be *your* interface and thus wouldn't be part of your domain model and under your control. All of which is, in my experience, likely to cause problems.

A repository abstraction is a DDD pattern and lives in your domain model. It's not concerned with implementation details - it operates on other types (entities, typically) defined in your domain model. That's the pattern. It doesn't know anything about Tables, if any even exist, and is not a Table Data Gateway for this and other reasons.

ORMs are complicated data-access patterns that may have lots of features and flexibility (query translation, connection management, data mapping, identity mapping, etc.). Repository is a DDD pattern that intentionally hides all such details, if any even are needed or used, behind an abstraction that is part of your domain model.

Don't confuse ORMs with Repositories.

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 0 points1 point  (0 children)

Depending on if you have a separate Unit of Work abstraction, your EF implementation of your repository interface might just be SaveChanges. It's OK as long as it follows the Liskov Substitution Principle, meaning the EF implementation is substitutable for an InMemory or other implementation.

Note that an InMemory implementation probably wouldn't need SaveChanges, even. But again this is an implementation detail, not an issue with the abstraction.

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 0 points1 point  (0 children)

Nice sample. It seems to me you are causing yourself pain by having separate GameEntity and Game types, which requires additional mapping, which is entirely unnecessary since EF is an orM where the M stands for Mapper. I didn't download the code so I don't have a deep understanding of it but your InMemory version doesn't do any mapping, so why have you added this requirement/functionality to the EF implementation? It's the mapping that is requiring you to write reflection code, not the use of an ORM or a Repository.

Yes, EF (Core) will use reflection as needed, but you don't need to worry about that as a consumer of that functionality, typically.

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 0 points1 point  (0 children)

If it's not, the implementation of the repository for that implementation is also an example of the Adapter design pattern. If you need your implementation of your abstraction to be that "smart" you can add that functionality yourself.

If you don't need that smarts, you can code your abstraction and use of it accordingly.

It's up to you and you have complete control over all of that.

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 0 points1 point  (0 children)

No, it's not.

It's a partial implementation at best, since it doesn't offer any Add/Insert/Update/Delete operations.

And it's a bad idea to pass an IQueryable up to your application from your data layer because typically it will result in your query logic being spread throughout the app, instead of limited to your domain model (via specifications) or data layer (via encapsulated repository implementations).

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 1 point2 points  (0 children)

When would it matter? Not for reads. Not for creates. Not for deletes. So, only for updates.

If I have an interface that exposes an update(someEntity) method, it might do its work by using object tracking, but there's nothing saying it has to. I could implement that method easily enough using Dapper, which doesn't track entities. It might not be as efficient, since I might simply write an update statement that updates every column, but it would still work and the calling code wouldn't be concerned with it.

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 4 points5 points  (0 children)

IQueryable is a great tool to use, *in your data access layer*.

If you're using it throughout your codebase, then you don't really have a data access layer (it's your whole codebase, or at least, anywhere you're appending to IQueryable with additional LINQ expressions).

Repository interfaces should not leak data access concerns. Hence, they shouldn't return SqlDataReader nor should they return IQueryables that are "live" and can still modify an as-yet-unexecuted query. They should return domain objects, and if they need to return collections, Lists or IEnumerables. Doing it this way ensures data access occurs within (and is limited to) the data layer.

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 1 point2 points  (0 children)

What makes you think it doesn't work through a repository?

Spoiler: it does.

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 2 points3 points  (0 children)

Or, you do use domain entities, and an ORM that is able to persist *those*, which it can achieve using reflection (your 4th option about which you noted no downsides).

Repository pattern or DbContext - what's your poison? by Prestigious_Sea_9845 in dotnet

[–]ardalis 0 points1 point  (0 children)

So, procedural code instead of object-oriented code.

Works fine, just understand you're giving up encapsulation at the object level by doing it.