Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
insta
Jan 28, 2009
So, I am web-retarded, but trying to get Blazor running. Since this is a proof-of-concept, I can use any version I want. What I'm running into is all the documentation is ... inconsistent at best. It seems like a lot changed between 3.0 and 3.1.

Does anyone have a good, known-to-work-with-3.1 guide for Blazor? I'm even having trouble with things like component tags (like <MyComponent> render in the browser DOM instead of running on the server), which seems like Blazor 101.

Adbot
ADBOT LOVES YOU

insta
Jan 28, 2009

mystes posted:

Perhaps I'm misunderstanding something since I've only messed around with Blazor a little bit and only Blazor Server, but if you're using it with webassembly isn't the whole point that it renders in the browser?

It literally puts <MyComponent> in the final markup instead of running the component :(

insta
Jan 28, 2009
Whenever I get bound-up on that kind of problem I will leverage my hosts file. Yeah, you have to add the port, but you can still get hosts in.

insta
Jan 28, 2009
Dictionaries are really, really fast. Millions of lookups per second on an average desktop.

insta
Jan 28, 2009

adaz posted:

this assumes the dictionary isnt huge but yeah in general I wouldn't worry about the 2 lookups. Chances are relatively high if the size of the dictionary is reasonable its a low value. The thing to worry about though is if you overriding gethashcode() and have a complex op in there. That _will_ destroy dictionary lookups.

I haven't really noticed slowdowns, unless I'm swapping. I use dictionaries for their insane lookup performance when running 5-8 million entries.

Definitely agreed on the GetHashcode performance though (and Equals).

insta
Jan 28, 2009

Boz0r posted:

I have a constructor that should only be called from a factory. How do I give the other devs a warning and refer them to the factory(also suppress the warning in the factory) if they try to use it? I was thinking of using Obsolete, but the constructor isn't obsolete.

Can you #pragma ignore the warning in the factory?

insta
Jan 28, 2009

Hughmoris posted:

If I don't have admin rights for a Windows 10 machine, what are my options for learning C#?

I have a lot of downtime currently at my job. I have vscode installed but I can't install the dotnet sdk and trying to manually compile my cs file using csc.exe is failing as well.

A second machine :/

insta
Jan 28, 2009
I still use l4n, but behind my own ILogger interface. It's worked well enough so far for me.

insta
Jan 28, 2009

NihilCredo posted:

If it's like most projects, 6-7 of those classes are basic stuff that virtually everything depends on, like loggers and databases. Wrap those in a "commons" POCO and inject that.

wtf no

insta
Jan 28, 2009

Boz0r posted:

I've been messing around with AutoFixture and AutoMoq and it's really cool, but I've hit a snag that I don't know how to solve. My code gets a bunch of proxies from a static factory class that I switch out with a mock factory in my test base class, and I use AutoDataAttribute to inject fixtures into my tests.

My mocking factory looks like this:
code:
public class ProxyFactoryMock : IProxyFactory
{
    private readonly IFixture _fixture;

    public ProxyFactoryMock(IFixture fixture)
    {
        _fixture = fixture;
    }

    public T GetProxy<T>(string url) where T : IProxyBase
    {
        return _fixture.Create<T>();
    }
}
I create an AutoMoq attribute like in their guide:
code:
public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute() : base(() => new Fixture().Customize(new AutoMoqCustomization()))
    {
    }
}
And I use it in my test definition like so.
code:
[Theory, AutoMoqData]
public void AutoProxyTest([Frozen] Mock<ISomethingProxy> somethingProxy)
{
	// Arrange
	somethingProxy.Setup(proxy => proxy.Method(It.IsAny<string>())).ReturnsAsync(() => new SwaggerResponse<string>(default, default, "test"));
	
	...
}
My problem here is, that the attribute and the factory have two different instances of IFixture, so the factory doesn't use the proxy I just set up.

How do I fix this in the neatest way, without having to add extra code to each unit tests, and also having the instance be unique per test?

Make the factory class injectable instead of static and swap factory implementations?

insta
Jan 28, 2009
Sounds like a use-case for T4

insta
Jan 28, 2009
Embrace CQRS. It flattens everything.

insta
Jan 28, 2009

MisterZimbu posted:

DI best practices question. Say I have a project already up and running that digests data in a database:

code:
public class AppSettings : IAppSettings {
  public string ConnectionString { get; set; }
}

public class DataProcessor : IDataProcessor {
  public DataProcessor(AppSettings settings) {}

  public void ProcessData() {
     ...
  }
}

public static class Startup {
  public void ConfigureServices(ServiceCollection sc) {
    sc.AddScoped<IAppSettings, AppSettings>();
    sc.AddScoped<IDataProcessor, DataProcessor>();
  }
}
I want to update the solution to be able to point at multiple databases. This there a best practice for parameterizing the services I've already written, without actually having to change the signature of every method in the class to take an additional parameter? Real solution has a larger number of services, and some of them reference other services, so I'm hesitant to go too deep in changing the method signatures, etc.

Currently I'm able to solve it by creating a "context" object that represents a single database, and update the services to have a dependency on that instead of referencing AppSettings directly. Then I create a scope in the ServiceProvider, and when looping through the databases, get a new context object and set the properties in that manually. It works, but it feels like there's a better way to go about doing this:

code:
public class DataProcessorContext : IDataProcessorContext {
   public string ConnectionString { get; set; }
}

public class DataProcessor : IDataProcessor {
  // change DataProcessor to take a context object instead of an AppSettings
  public DataProcessor(IDataProcessorContext context) {}
}

public class AppSettings : IAppSettings {
  public string[] ConnectionStrings { get; set; }
}

public class DataProcessorLoop : IDataProcessorLoop {
  public void ProcessData() {
    foreach(var cs in appSettings.ConnectionStrings) {
      using(var scope = serviceProvider.CreateScope()) {
        var context = scope.ServiceProvider.GetRequiredService<IDataProcessorContext>();
        context.ConnectionString = cs;

        var processor = scope.ServiceProvider.GetRequiredService<IDataProcessor>();
        dataProcessor.ProcessData();
      }      
    }
  }
}
Apologies in advance for the incomprehensible XY problem post

Don't inject IAppSettings, but instead inject your own IConnectionStringProvider. Then, use the "for X class dependency Y, use implementation Z". The code for Lamar is approximately:
code:

public class DataProcessor : IDataProcessor {
  public DataProcessor(IConnectionStringProvider csp) {}
}

IoC.Configure(c => {
  c.For<IDataProcessor>.Use<DataProcessor>.Ctor<IConnectionStringProvider>().Is<AppleDatabase/BananaDatabase/CherryDatabase>();
});


insta
Jan 28, 2009

Calidus posted:

Anyone have positive or negative experiences with Math.NET? I need to rewrite someone else’s Matlab code. I have much more experience with .NET than python.

I wasn't a fan the 19 minutes I played with it. It is probably a very authentic port, but it's not very .NET friendly. A lot of the method calls are static calls, and they update the parameters passed in, and that's gross to me.

insta
Jan 28, 2009

Withnail posted:

lol I need to refactor hundreds of legacy classes. That would not be time efficient.

Sounds like you need Roslyn!

insta
Jan 28, 2009

raminasi posted:

Then I'm not explaining it right. It was basically this:
C# code:
public async Task AsyncThing()
{
    await InnerCall(); // no ConfigureAwait but it worked anyway
}

public void BadButWorkedAnyway()
{
    AsyncThing().Wait();
}
They added a second await to `AsyncThing`, which caused a deadlock. Yes, the code was wrong originally (which static analysis would have caught), but "combining .Wait() and await causes deadlocks" did not fly as an explanation when the code had already been doing that without deadlocking.

Is it ok to do this? :ohdear:
C# code:

public async Task AsyncThing()
{
   await InnerCall();
}

private async Task InnerCall()
{
   await LongThingy1();
   await LongThingy2();
}
Should I do it a different way?

insta
Jan 28, 2009
How do I safely "get into" an async/await stack if I'm not in one to begin with?

insta
Jan 28, 2009
Just checking, the API isn't WCF, is it? If so, you can generate client-side code with a single command that does *alllll* that crap for you.

insta
Jan 28, 2009
Seconding learn how LINQ works (specifically LINQ-to-objects). It is NOT just a database provider.

Be very comfortable with generics, async/await, and rudementary data structures (HashSet is usually what you want when using List, for instance). With that much background in PHP you'll probably be going full-stack/frontend, so brush up on Razor Pages and how they're different than MVC. Depending on how you wrote your PHP, Razor Pages may feel completely at home.

insta
Jan 28, 2009
Dolemite you're going to do fine in .NET. You clearly show enough aptitude that any decently competent interviewer will let you reason yourself into the answer they want to hear (your thinking along Func/Action sold me).

Now go learn that var is good and is not dynamic and you're golden.

insta
Jan 28, 2009
I'm an always-var after being stymied at big refactors because of things like this:

code:

public IList<string> GetFoos() { ... }
//to
public IEnumerable<string> GetFoos() { ... }

This kind of thing works fine if all the consumers are "var" to the method. But, it's super common (and advocated by the thread!) to do this:

code:
List<string> values = GetFoos();
//instead of:
var values = GetFoos();
Keeping things as var across my (large) projects really does allow for faster and more seamless refactoring.

insta
Jan 28, 2009
sorry your variable names and ide suck

insta
Jan 28, 2009
The difference is that dynamic actually sucks though

insta
Jan 28, 2009
Can't you use the Func itself as a key? I know you can with a Dictionary.

insta
Jan 28, 2009
Thirding "don't worry about it". Your constructors aren't doing anything except storing a reference to other items anyway, no actual work happens in them (riiiiiiight? :colbert:), and references are cheap.

insta
Jan 28, 2009
HAP exposes the DOM via IEnumerable<HtmlElement>, so you can write LINQ against that. It will be regular LINQ-to-Objects, but I don't know if that's missing anything that System.Xml.Linq has.

insta
Jan 28, 2009
:colbert: that's a 404

insta
Jan 28, 2009
gently caress i am stealing all that. I literally just wrote an article on our corporate wiki about why we implement the IConverter<TIn, TOut> interface manually instead of AutoMapper.

Also gently caress any team that buries AutoMapper directly in code instead of behind an interface.

insta
Jan 28, 2009
That is exactly what a service bus is for. Like, all of it.

insta
Jan 28, 2009

Funking Giblet posted:

Improved pattern matching makes generic exceptions easier to work with.

The language designers had to add this because everybody involved is garbage at exceptions and exception hierarchies. It's literally 90 seconds to add a new exception type yet somehow that's too much work. Throwing 'new Exception ($"Unable to load {id} from database")' is apparently way better than "new MissingDataException(id)" for reasons I'll never understand.

Bonus if you catch the actual exception and throw your own Exception (not even any subtype!) without including any of the original context.

Or double bonus if you catch(Exception e) { throw e; } and blow away my stack trace when I'm trying to debug logs from prod.

Or super gently caress you if you catch(Exception up) { throw up; /* he he he */ } like the actual code I found, complete with "he he he" in a comment.

insta
Jan 28, 2009

salisbury shake posted:

If I'm a Linux user who will never use the .NET platform on Windows, how painful is it to use F# for application, system or web development?

F# is as platform-agnostic as C# is. The underlying library also got very cross-platform in Core, and continues to do so.

You as the developer will be the weak link, doing things like concatenating paths together instead of using Path.Combine.

VSCode and 'dotnet' will do a lot more than you'd think they will!

insta
Jan 28, 2009
Just an FYI if you're not aware, RavenDB is actually really cool, and not like any database you're used to using.

insta
Jan 28, 2009

Mata posted:

I've been finding myself reinventing List<T>, because I need to store my data as an array for non-managed reasons, but generally want all the list-like behavior when it comes to adding and removing items. This has left me wondering though, since lists are built on top of arrays, is there any reason why I couldn't just yoink the internal array, like so:
C# code:
FieldInfo fi = typeof(List<Matrix>).GetField("_items", BindingFlags.Instance | BindingFlags.NonPublic);
Matrix[] innerArray = (Matrix[])fi.GetValue(myList);
var ptr = GCHandle.Alloc(innerArray, GCHandleType.Pinned);
OpenGL.SetData(ptr) // etc
I'm not sure if this is a good idea (or if it's a great idea), but the implementation of list doesn't vary, right? And there's no optimizations done on any level that could break this? Assuming .ToArray makes a defensive copy, this seems like it would be faster.

Please don't write murderous-rage-inducing "clever code" on the assumption it's faster without actually profiling it.

There are a lot of things the JITer can do if you give it code it's familiar with.

insta
Jan 28, 2009

New Yorp New Yorp posted:

Why trigger on a timer? It seems like you'd want to use a queue and skip the blob storage bit entirely.

NO QUEUE.

ONLY FIRST-IN FIRST-OUT MECHANISM WITH PERSISTENCE.


I have no idea why so many teams gently caress up queues *so badly*

insta
Jan 28, 2009
thats the joke.


So many teams will reinvent queuing mechanisms with databases and polling instead of just using a queue.

insta
Jan 28, 2009
I just went through this!

The Configuration system in Core (and above) is a hierarchical, multi-layered providers-based approach. All configuration key/values are ultimately turned into a colon-separated key, with a value. So, the following JSON becomes:

code:
{
   "auth" : {
      "keys" : {
          "prod" : "abc123"
       },
       "lifespan" : {
           "passwords" : "30",
           "tokens" : "3600"
       }
   }
}

"auth:keys:prod" : "abc123",
"auth:lifespan:passwords" : "30",
"auth"lifespan:tokens" : "3600"
What's important here is the second part, the colon-separated strings. If you override a ConfigurationSource, you can call "Set" yourself and plop arbitrary config values into the config hierarchy. We do this at work to load things from a database (in a config that does not understand proper hierarchy). We also hardcode defaults in one provider, read from appsettings.json, read from the DB, and read from multiple XML files.

So, if you have multiple sources, what gets updated on Save?

insta
Jan 28, 2009
Glad they didn't waste too much time making the esoteric thing of "web requests" too easy.

insta
Jan 28, 2009
There's also the option of closing the tickets after a period of inactivity, and blaming the ineffective user on it. Public shaming is a powerful tool.

quote:

Ticket #555123 has been closed by some.butthole after 6 days of inactivity. The ticket was assigned to some.butthole on 2021-10-19 and has not been updated in 7 days.

insta
Jan 28, 2009
Yeah, BackgroundWorker is exactly what you're looking for. They run when your app pool starts, stop when you app pool stops, and are in the same process space for easy communication between web and service.

If you have a Singleton instance between the web and service, you can have the web project directly talk to data populated by the service (like an in-memory ConcurrentDictionary).

Adbot
ADBOT LOVES YOU

insta
Jan 28, 2009
Quick and dirty solution: chuck a .ToList() on the Messages inside the loop.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply