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
Dirty Frank
Jul 8, 2004

I have a requirement to write a console app which can perform migration operations from different versions of our software (an fairly complex enterprise horror), one after another to take us from 1.0 all the way to say 2.6

My thought to achieve this was:

1) a console app outside of our normal release schedule untied to any of our versioned dlls, which would use a class lib assembly also untied to any of our versioned dlls.
2) each release implements its own migration operations in a dll which would implement some interface from the class lib in 1)
3) the console app (or more accurately its class lib) would consume the migration operations dlls and call migrations in some order defined in some text format according to the customers version of our software.

So we end up then with several migration operation dlls e.g. Which gives headaches with dll versioning. I believe I need to use AppDomains to separate them.

1.0 -> 1.1 migration operation dll which references MyCompany.Dothings.dll (version 1.0)
1.1 -> 1.2 migration operation dll which references MyCompany.Dothings.dll (version 1.1)

I started looking into MAF to do this https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-4.0/bb384200(v=vs.100)

However it seems like maybe support for this is not particularly active.

Given the above is there a ideal way to do this?
Does anyone have experiance with MAF?
And am I even thinking along the right lines for this?

Adbot
ADBOT LOVES YOU

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Dirty Frank posted:

So we end up then with several migration operation dlls e.g. Which gives headaches with dll versioning. I believe I need to use AppDomains to separate them.

I don't know about the rest but I'm pretty sure you don't need to separate them into different AppDomains. The documentation will tell you that you need to load an assembly "into an AppDomain" but to be very precise, it's not stating "into a unique AppDomain." I had to work on a project once where I was pretty sure they got that notion and it was its own kind of hell. The reason to have that separation is if:

1. The stuff you're loading risks being complete poo poo.
2. The hosting application has such a large uptime and the stuff your loading is small in comparison. Hence, you want to unload the stuff afterwards.

If this is a separate application that's running the migration, and you don't have 3rd party developers involved, you should be able to load into the current AppDomain. To make life a little bit easier, you should have something in the interfaces that states the migration paths the code supports. I couldn't tell from what you were writing out if you were intending to infer that from the assemblies. At that point, the assembly version doesn't matter as much; X version 1.0 that migrates 1.0->1.1 vs Y version 1.1 doing 1.1->1.2 are apples and oranges and might as well have completely different names and versions.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Rocko Bonaparte posted:

I don't know about the rest but I'm pretty sure you don't need to separate them into different AppDomains. The documentation will tell you that you need to load an assembly "into an AppDomain" but to be very precise, it's not stating "into a unique AppDomain." I had to work on a project once where I was pretty sure they got that notion and it was its own kind of hell. The reason to have that separation is if:

1. The stuff you're loading risks being complete poo poo.
2. The hosting application has such a large uptime and the stuff your loading is small in comparison. Hence, you want to unload the stuff afterwards.

If this is a separate application that's running the migration, and you don't have 3rd party developers involved, you should be able to load into the current AppDomain. To make life a little bit easier, you should have something in the interfaces that states the migration paths the code supports. I couldn't tell from what you were writing out if you were intending to infer that from the assemblies. At that point, the assembly version doesn't matter as much; X version 1.0 that migrates 1.0->1.1 vs Y version 1.1 doing 1.1->1.2 are apples and oranges and might as well have completely different names and versions.

Couldn't you have type version conflicts if the migration DLLs aren't really carefully written or would segregated AppDomains not help with that?

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Munkeymon posted:

Couldn't you have type version conflicts if the migration DLLs aren't really carefully written or would segregated AppDomains not help with that?

Yes. (to both)

It looks like there is a good, specific purpose for these assemblies. They are not participating in a distributed architecture where these things need to be popped in and out. So that should curb on the possible shenanigans, but it's amazing how innovative people can be when doing something stupid.

The most common problem I remember was reusing the same name and version when trying a work-in-progress assembly in an environment that stayed resident between each load. I think that environment could have been more diligent about shedding the old assembly and reloading it. Regardless, that thing was using separate AppDomains and it did nothing to help there how it was written.

Now, if the problem instead was that this was some distributed architecture that introduced APIs and stuff that could wander around the system, then Hoooly poo poo you should segregate that and also question your life decisions. The take I got of the problem was it was a plug-in system that got in, migrated some poo poo, and got out.

Edit: and also I am assuming these imported assemblies are trusted.

Rocko Bonaparte fucked around with this message at 19:41 on Aug 13, 2019

Dirty Frank
Jul 8, 2004

Munkeymon posted:

Couldn't you have type version conflicts if the migration DLLs aren't really carefully written or would segregated AppDomains not help with that?

This is the problem I think AppDomains will help with. However! it seems AppDomains won't be present in .net Core at all and we will be porting to Core at some point in the future.

So now the plan is to have a standalone migrator console app in each release (I mean in practice the code won't change much but they will be packaged separately in the release) which implements its own migration operations and some kind of Orchestrating app external to the release cycle which will call, not directly but as console apps, each versions migrator console app in order to go from start version to target version. Which I kind of like because I understand everything required.

Seems like we're rolling a solution to a common problem though?

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

Dirty Frank posted:

This is the problem I think AppDomains will help with. However! it seems AppDomains won't be present in .net Core at all and we will be porting to Core at some point in the future.
Oh wow!

Did you happen to see in that what they intended to use instead of AppDomains? I've always seen some value in it to be able to upgrade and replace bits of code in a long-running application. Then again, it looks like the industry has switched over to commoditized cloud applications that can be taken up and down in bulk at-will. So upgrading generally just means shutting down the old instances and starting up the new ones. So maybe they're just decided to abandon the whole notion?

Edit: Found it.

quote:

On .NET Core, the AppDomain implementation is limited by design and does not provide isolation, unloading, or security boundaries. For .NET Core, there is exactly one AppDomain. Isolation and unloading are provided through AssemblyLoadContext. Security boundaries should be provided by process boundaries and appropriate remoting techniques.

So it looks like they're trying to apply some lessons learned or something.

Rocko Bonaparte fucked around with this message at 22:32 on Aug 13, 2019

LongSack
Jan 17, 2003

My favorite feature of C# 8 - switch expressions. They read cleaner to me. For example:
C# code:
[ValueConverter(typeof(bool), typeof(Uri), ParameterType  = typeof(string))]
public sealed class BoolToCheckmarkConverter : IValueConverter
{
    public object Convert(object value, Type t, object parm, CultureInfo lang)
    {
        string fallback = null;
        if (parm is string)
        {
            fallback = parm as string;
            if (string.IsNullOrEmpty(fallback)
            {
                fallback = null;
            }
        }
        if (!(value is bool val))
        {
            val  = false;
        }
        return (val, fallback) switch 
        {
             (true, _) => new Uri(Constants.Checkmark, Urikind.Relative),
             (false, null) => null,
             _ => new Uri(fallback, Urikind.Relative)
        }
    }

    public object ConvertBack(object value, Type t, object parm, CultureInfo lang)
    {
        return DependencyProperty.UnsetValue;
    }
}
I’m less enthralled by the new using thing. Sure, it fixes the “problem” of mega-nested usings (my StringCypher class’ Encrypt and Decrypt methods have like 5 nested using blocks, so by the time you get to the innermost, like half of the screen is whitespace, but I’m not sure the new method is clearer. I think I’ll get used to it.

Some WPF things that are different ...
  • Properties.Settings.Default is (at least for now) gone. Workaround (for me) is to put settings in the database, which I actually like better, putting stuff in the database rather than storing it in some directory under AppData.
  • Issues with image resources. Default build action for images is “None” when it used to be “Resource”. This will probably get fixed, but for now, select all your images and change them. Even after doing that, some parts of WPF don’t work. For window icons, where I used to be able to do Icon=”/resources/foo.png”, I now need to do Icon=”pack://application:,,,/FooAssembly;component/resources/foo.png”. I’m hopeful that this will be fixed, too.
  • Inconsistencies with attached behaviors. Since I use the MVVM pattern, I used attached properties to handle events like WindowLoaded, MouseDoubleClick, etc. like for WindowLoaded, it looks something like:
    C# code:
    Window ...
        xmlns:fi=”clr-namespace:Foo.Infrastructure” ...
        fi:Behaviours.WindowLoadedBehaviour={Binding WindowLoadedCommand}”
    But sometimes, the command just doesn’t get called. Only workaround for this is code-behind :chloe:
Anyway, this has been your trip report.

Macichne Leainig
Jul 26, 2012

by VG
That’s some interesting syntax, took me a minute really digest what’s going on. Very cool.

Xik
Mar 10, 2011

Dinosaur Gum
There is some interesting stuff. They added default implementations for an interface which I wouldn't have expected.

The new switch is nice, it reads like pattern matching in F#. ^ and .. for array slicing is also cool. Maybe if we wait long enough C# and F# will just be the same language :v:

Mr Shiny Pants
Nov 12, 2012

Xik posted:

There is some interesting stuff. They added default implementations for an interface which I wouldn't have expected.

The new switch is nice, it reads like pattern matching in F#. ^ and .. for array slicing is also cool. Maybe if we wait long enough C# and F# will just be the same language :v:

One can dream......
They do copy a lot from it considering they always treat it like a redheaded stepchild.

Mr Shiny Pants fucked around with this message at 06:05 on Aug 19, 2019

Cuntpunch
Oct 3, 2003

A monkey in a long line of kings

Mr Shiny Pants posted:

One can dream......
They do copy a lot from it considering they always treat it like a redheaded stepchild.

It's weird because quite a few CLR-level changes seem to be implemented to give F# support for things, and then years later C# gets implementations of those same features.

redleader
Aug 18, 2005

Engage according to operational parameters
I'd like Result<TResult, TError> and Option<T>/Maybe<T> types in the standard library tbh. F# has standardised these types in its ecosystem - it'd be nice if .NET could have standard ones so I don't need to think about rolling my own or choosing one of the many slightly- different equivalents in Nuget.

Cuntpunch
Oct 3, 2003

A monkey in a long line of kings
These great features and more are waiting for you by just using F# - Call now for your introductory offer of Nobody Else Gets It Jesus Christ Why Cant We Use F# Around Here Come On Guys Its Not That Scary Wait What Are Those Pitchforks For

nielsm
Jun 1, 2009




Nice, they added constreadonly correctness. Thank you C++.

What's the difference between an interface with default members and an abstract class with partial implementation?

SirViver
Oct 22, 2008
I guess the main difference would be that you can implement any number of interfaces but you can only derive from one abstract class. E: Also, the interface default members obviously can't access any class instance members, except through reflection (yuck).

SirViver fucked around with this message at 09:30 on Aug 19, 2019

No Pants
Dec 10, 2000

A big one is that classes don't inherit interface members (they implement them). That means to use a default implementation, you have to cast an instance of the class to the interface, similar to how you'd use explicitly implemented interface members.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.
edit: nevermind

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



LongSack posted:

I’m less enthralled by the new using thing. Sure, it fixes the “problem” of mega-nested usings (my StringCypher class’ Encrypt and Decrypt methods have like 5 nested using blocks, so by the time you get to the innermost, like half of the screen is whitespace, but I’m not sure the new method is clearer. I think I’ll get used to it.

Nesting usings is the one place I don't mind omitting braces+indenting for the scope(s) so it's kinda whatever

Hughmoris
Apr 21, 2007
Let's go to the abyss!

Cuntpunch posted:

These great features and more are waiting for you by just using F# - Call now for your introductory offer of Nobody Else Gets It Jesus Christ Why Cant We Use F# Around Here Come On Guys Its Not That Scary Wait What Are Those Pitchforks For

What are some of the projects/scripts you've used F# for?

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

Hughmoris posted:

What are some of the projects/scripts you've used F# for?

fscheck is real good

Cuntpunch
Oct 3, 2003

A monkey in a long line of kings

Hughmoris posted:

What are some of the projects/scripts you've used F# for?

Figuring out F# is my boredom project of the year, so it's not like I have F# in production to refer back to. So far a lot of it has been 'ok take a problem I'd consider trivial to solve in C# and figure out how to think about it from a different direction and work it out functionally.

My quip comes from experiences in trying to discuss how I've got this strong feeling there is really something super valuable there, and a lot of C# developers I know have the identical reaction of "But...why? I can do all of that faster and easier in C#!"

Ape Fist
Feb 23, 2007

Nowadays, you can do anything that you want; anal, oral, fisting, but you need to be wearing gloves, condoms, protection.
I have a little ga ga goo goo baby C# question I've been going TypeScript for like 2 years now as an FED and I figure C# is a good sort of back-end language to actually pick up outside of the Node environment and I work in a .NET house so I guess its useful.

I was passing an argument into a nested function inside a method and it got snotty about types. Fine, normal. The idea of the function is pretty simple:

code:
            void TypeTester(IncomingArg) 
            {
                Console.WriteLine(IncomingArg.GetType());
            }
Obviously this didn't work because the agument wasn't typed, but I want the argument to be generic, so I did this:

code:
            void TypeTester<Any>(Any IncomingArg) 
            {
                Console.WriteLine(IncomingArg.GetType());
            }
This worked, but I have 3 questions.

1. Why did it work?

2. Is this bad practice?

3. What is better practice?

mystes
May 31, 2006

Why wouldn't it work? You can just use Object though.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Ape Fist posted:

I have a little ga ga goo goo baby C# question I've been going TypeScript for like 2 years now as an FED and I figure C# is a good sort of back-end language to actually pick up outside of the Node environment and I work in a .NET house so I guess its useful.

I was passing an argument into a nested function inside a method and it got snotty about types. Fine, normal. The idea of the function is pretty simple:

code:
            void TypeTester(IncomingArg) 
            {
                Console.WriteLine(IncomingArg.GetType());
            }
Obviously this didn't work because the agument wasn't typed, but I want the argument to be generic, so I did this:

code:
            void TypeTester<Any>(Any IncomingArg) 
            {
                Console.WriteLine(IncomingArg.GetType());
            }
This worked, but I have 3 questions.

1. Why did it work?

2. Is this bad practice?

3. What is better practice?

1. You stumbled across the syntax for generics in C#. Generally people will write this as
code:
 void TypeTester<T>(T IncomingArg) 
{
   Console.WriteLine(IncomingArg.GetType());
}

if you want to be more idiomatic about it.

2. No.

Hughmoris
Apr 21, 2007
Let's go to the abyss!

Cuntpunch posted:

Figuring out F# is my boredom project of the year, so it's not like I have F# in production to refer back to. So far a lot of it has been 'ok take a problem I'd consider trivial to solve in C# and figure out how to think about it from a different direction and work it out functionally.

My quip comes from experiences in trying to discuss how I've got this strong feeling there is really something super valuable there, and a lot of C# developers I know have the identical reaction of "But...why? I can do all of that faster and easier in C#!"

I'm a novice hobbyist and struggle with designing OOP stuff so I was curious about trying my hand at FP. I've heard good things about F#.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Ape Fist posted:

...

This worked, but I have 3 questions.

1. Why did it work?

2. Is this bad practice?

3. What is better practice?

The only thing you did with the argument is call its method GetType(). GetType() is a method on object. Every non-static type inherits from object (either directly or indirectly), so that's OK to do regardless of the type of object. If you were doing something with your Any that required more of it than just being an object, you would have had to place constraints on it or the compiler wouldn't have allowed it.

But as someone else said, you could have instead declared the parameter to be of type object and that would arguably be better style since what you're using is the fact that the parameter is of type object; you're not really using the "genericness" of the method.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Hammerite posted:

The only thing you did with the argument is call its method GetType(). GetType() is a method on object. Every non-static type inherits from object (either directly or indirectly), so that's OK to do regardless of the type of object. If you were doing something with your Any that required more of it than just being an object, you would have had to place constraints on it or the compiler wouldn't have allowed it.

But as someone else said, you could have instead declared the parameter to be of type object and that would arguably be better style since what you're using is the fact that the parameter is of type object; you're not really using the "genericness" of the method.

A general guideline which may be useful for someone coming from untyped/weakly-typed languages:

If you're passing around things as object and casting them, or if you're doing a lot of if (someObject is SomeType), you almost certainly have a design problem.

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost

Hughmoris posted:

What are some of the projects/scripts you've used F# for?

We have a few internal sites that use Suave for F# web hosting, and the majority of the publishing process of Xamarin uses is in F#, which includes the tools/scripts used to insert our products into VS and VS For Mac.

Cuntpunch
Oct 3, 2003

A monkey in a long line of kings

Hughmoris posted:

I'm a novice hobbyist and struggle with designing OOP stuff so I was curious about trying my hand at FP. I've heard good things about F#.

I think F# is a nice sweet spot for functional stuff. Haskell may be more pure and academic, but it's also in its little world. Clojure is cute and has interop with a major OO ecosystem, but the last time I looked at it, I found the tooling wanting - and the Lisp 'look' to be more difficult to follow.

I'd be curious what pain points you're feeling around OOP design, though - I've heard FP described as a very pure version of applied OOP.

Drastic Actions
Apr 7, 2009

FUCK YOU!
GET PUMPED!
Nap Ghost
F# is great because you can ease your way into functional programming with it. You can treat it as weird C# and start refactoring code as you start to think about better ways to rewrite to make it smaller and more functional, as it were.

Getting hung up on the “functional” part (and being told by functional programming-heads how you’re doing it wrong et all) by going all in is tough, but you can ease your way into it.

raminasi
Jan 25, 2005

a last drink with no ice

Hughmoris posted:

What are some of the projects/scripts you've used F# for?

I have found production F# in a C# shop useful in two places:
  • You're already using fully immutable models and you want better language support for doing so
  • Your business logic is abstractable
As an example of the second, I had great success using F# to create an application that implemented arithmetic defined in a variety of separate but similar contracts. F# allowed us to create a pseudo-DSL that we could use to encode and easily modify contract definitions, and we spun up a complicated, maintainable greenfield project way faster than anyone expected. I also created a rich library that sat in front of a "dumb" one and added a bunch of functionality that was generic over a variety of different APIs, allowing the rich library to be implemented much more simply than one that would have had to repeat logic multiple times because C# didn't have sophisticated enough abstraction tools.

FsCheck is indeed great, but you're not going to be able to get a team to learn an entirely new language just to write tests, especially because FsCheck requires you to use one of the most alien features in the language.

There may be more uses of F# that work, these are just the ones I'm aware of. For typical boring line-of-business applications, F# has the weakness that there is no standard project organization the way there is with C#, so you have to spend a little time explicitly deciding on one. If your entire team is already fluent in F# this might be worth it (people who like F# tend to be more productive in it than, say, C#) but I haven't yet found a business case when there's a learning curve that matters.

e: also the tooling is always a few steps behind

LongSack
Jan 17, 2003

How do you all handle string literals? For strings that appear more than say 2 or 3 times, I have a Constants class (which also has ‘numbers’ like exit codes, etc.), but for strings that are one-offs, I just code them inline. Obviously my apps are not internationalized. I recently installed a Microsoft code analyzer (and quickly uninstalled it) which bitched at literally every string literal saying it should be from a resource dictionary instead.

So what do you all do?

Cuntpunch
Oct 3, 2003

A monkey in a long line of kings

raminasi posted:

FsCheck is indeed great, but you're not going to be able to get a team to learn an entirely new language just to write tests, especially because FsCheck requires you to use one of the most alien features in the language.

The joy here for me is that since it's all CLR, you can use FsCheck in your C# unit tests just as easily.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

LongSack posted:

How do you all handle string literals? For strings that appear more than say 2 or 3 times, I have a Constants class (which also has ‘numbers’ like exit codes, etc.), but for strings that are one-offs, I just code them inline. Obviously my apps are not internationalized. I recently installed a Microsoft code analyzer (and quickly uninstalled it) which bitched at literally every string literal saying it should be from a resource dictionary instead.

So what do you all do?

I have sometimes done this Constants class thing you describe, but it's usually for things that are internal and not user-facing, e.g. the names of config setting keys, default values for configuration settings, and such. I'm not sure I'd store messages for the user that way, even if the app isn't internationalised and the strings are all in English I might keep them closer to the point of use - or in any case, separate from the more "techy" constants.

e: when I've done this it has been in ASP.NET projects. It's convenient to be able to write using static MyProduct.MyProject.Constants; at the top of Startup.cs.

Hammerite fucked around with this message at 09:53 on Aug 20, 2019

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I mean, why not just use resources like the analyser suggests? It's easy enough to set up, and once you've done it the usage is basically identical to your constants class anyway.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Jabor posted:

I mean, why not just use resources like the analyser suggests? It's easy enough to set up, and once you've done it the usage is basically identical to your constants class anyway.

I would like to preface this by saying that I don't want to appear emotionally invested in doing things the way I described in my post, so please don't interpret this that way.

Your suggestion is devoid of reasons to do as you suggest. You say that it's "easy enough to set up" - OK, but that's not a reason to do as you say, it's merely the absence of one specific reason not to. It isn't, on its own, a basis for choosing a course of action. And the alternative you're contrasting it with (creating a constants class) is at least equally easy; easier if you haven't set up a resource dictionary before, because it doesn't come with the overhead of having to figure out how to do that (whereas I already know how to type stuff into a file of C# source).

In addition, there is a heuristic that applies to suggestions that run along the lines of "why not do things using (piece of machinery that's part of the framework)?" which is "does it seem like the kind of thing that will at some point become 'the old way' of doing things?" Maybe resource dictionaries have been around since .NET 1.0 and are unlikely to ever change, or maybe they were added last week and will change at the drop of a hat, I don't know. But there are aspects of .NET these days that change rapidly (particularly in the area of ASP.NET Core), and if something smells like a thing that will become obsolete at some point, that's a basis for being wary of it. To me, as someone who doesn't know what a resource dictionary is or how stable a feature it is, your suggestion has that smell.

e: I would follow this up by acknowledging that the considerations I outline in the previous paragraph are very weak reasons for choosing a course of action, and might be easily overturned by somebody posting a list of reasons why resource dictionaries are actually really good and worth using. However, weak as they are, they are still more than the zero reasons you provided.

Hammerite fucked around with this message at 11:18 on Aug 20, 2019

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I mean, the baseline evidence in favour is that "Microsoft's code analyzer is recommending them", which certainly suggests that they're the generally recommended way to handle UI strings - or at least worthy enough to look into rather than uninstalling the analyzer in a huff.

brap
Aug 23, 2004

Grimey Drawer
Also it’s not hard to suppress a particular diagnostic ID if you’re not interested in it.

LongSack
Jan 17, 2003

Jabor posted:

I mean, the baseline evidence in favour is that "Microsoft's code analyzer is recommending them", which certainly suggests that they're the generally recommended way to handle UI strings - or at least worthy enough to look into rather than uninstalling the analyzer in a huff.

Not a huff, so much, more a realization that i'm 30,000 lines of code into this app, that's 1/3 to 1/2 done, and there's no way i'm going to refactor every single string into some resource dictionary lookup.

Maybe next project.

Adbot
ADBOT LOVES YOU

LongSack
Jan 17, 2003

Thinking more about this, how does it work? If we’re talking about a literal ResourceDictionary, then each string needs a key which is, itself, a string. So is fxcop gonna bitch at me about using string literals as key values?

And what do you use as key values? Either a key that’s descriptive enough that someone reading the code has an idea what the string is, or else something like ”MSG0000001” in which case whoever is reading the code needs to keep the dictionary up in another monitor to see the messages.

Obviously, I’ve never done this before, so I could be missing something blindingly obvious (wouldn’t be the first time; won’t be the last), but it seems like I’m replacing one set of strings (values) with another (keys), and short of localization, I don’t see an advantage.

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