Re: Creating a "public only" constructor
Frans Bouma <[email protected]> Mon, 6 Apr 2009 12:55:48 +0200
| Newsgroups | gmane.comp.windows.devel.dotnet.advanced |
|---|---|
| Message-ID | <006e01c9b6a6$3ec2f400$bc48dc00$@nl> |
> It is template based - but a bespoke generator. > > "As is't the default ctor you're worried about, it's easy to spot with > search/replace" > > Not with over 500 classes in 3 million lines of code it's not. sure it is. InvoiceItem ii = new InvoiceItem(); you can search replace every single InvoiceItem(); calls to a call to a factory, in 1 go. But Im sure you already knew that, so I think we're not talking about the same thing here. > There is no order of constructors. The "normal" apps which consist of about > 5 Windows Applications and 15 to 20 Web applications always use the > defaults, as has be the case for the past 8 or 9 years. Using the defaults > causes the underlying class factory to use the defaults also, which is > perfect for those apps. > > The scenario we have is we need to instantiate the same class on 2 different > servers, and clone one to the other. My issue is if I instantiate an Invoice > class using the second constructor to point it directly to it's server, that > the existing code might not point all child objects to the same server if > they call the default constructor. And there is 8 to 10 years worth of code > already in there, so there is a *VERY* high chance that it uses the default > constructor. Hence why I was looking for a way to "block" the default > constructor from being used insite the assembly. I'm sorry if I sound rude, but isnt this design going to make things only less maintainable? I mean: to me it sounds like a very error prone way to have objects instantiating and then make sure the right ctor is called otherwise the object might end up in a different environment and likely one will only find out way too late at runtime. So, if you're worried about having child objects (which is a vague concept btw, it's not clear what that means. A 1:n B doesn't mean B is a child of A) being instantiated in a wrong way, make them only instantiateable through the 'parent'. YES this will take time to fix it, but IMHO the only way to make this codebase survive the next couple of years and to avoid making it less maintainable, this is something that should be done. Not all classes are a candidate for being a child object. Identity which classes are. Then identify which parents should be instantiators for these children. then extract where these children are instantiated and analyse these instantiations, it's likely that there's some kind of pattern used, so you might be able to adjust smaller parts of code to fix it for more instantiations (e.g. a helper method is called for a lot of cases). Only then you'll know the impact of this change. But it won't get any better by simply block a ctor. if you want to block a ctor you have to provide a different route to instantiate the class. Quick hacks might work now, but who will fix it properly next year, or over 2 years? > Trust me - if the default cannot be blocked, then there are no other > options. Search and replace is not an option. Even putting attributes or > demands on the constructors requires someone to hand code all 500 > constructors... Let me state it bluntly. You have two options: 1) fix it properly, which takes perhaps some time but will make the codebase survive the next couple of years 2) ignore it and toss the codebase out and start over. a quick hack is more permanent than you might think, which will cause more harm than good. Codebases in general become less and less maintainable because more and more quick-hacks are applied to them and which are never really fixed properly because to do that one needs a lot of time (similar to the first time). However, rewriting it is even more costly. If your employer doesn't want to fix it properly, of course your hands are tied, but there are little other options. FB > > Dino > > -----Original Message----- > From: Discussion of advanced .NET topics. [mailto:ADVANCED- > [email protected]] On Behalf Of Frans Bouma > Sent: Monday, 06 April 2009 20:34 > To: [email protected] > Subject: Re: [ADVANCED-DOTNET] Creating a "public only" constructor > > > If it were a new design yes - but it's not. The code generation has > allowed > > for this separate server capability, but I fear it cannot be utilised > fully > > because the code was historically never designed to work with it, and > > without hundreds of hours of trawling through the current codebase it > can't > > be successfully changed to a class factory type scenario. > > If the code generation was template based, you might be able to do > something about it, but I'm not sure how it's generated. > > Refactoring the code might be simpler than you might think. As is't > the default ctor you're worried about, it's easy to spot with > search/replace. if you load the codebase into vs.net, and do find/replace in > files, and replace the call to the empty ctor to a call to a factory, the > only thing that's to solve after that is the references to the right > namespace where the factory is located. You can also spot calls to the > second ctor with a simple regex in the find/replace dialog in vs.net. > > But I still don't fully understand what the order is in which the > ctors are used. As I understand it, it seems that if I want to instantiate > an invoice, I use the empty ctor of Invoice. And if I want to instantiate an > invoiceitem, I use the parameter-using ctor in invoice, and you want to > prevent that the invoiceitem empty ctor is used, correct? > > If you replace calls to both ctors to a call to a factory and make > both ctors internal, you have full control over when what is called. > However, I am a bit puzzled why the empty ctor is supposed to be public if > instantiating an invoiceitem is always dependent on the invoice itself (as > instantiating it on the same server as the invoice is always the best idea) > > FB > > > > > Dino > > > > -----Original Message----- > > From: Discussion of advanced .NET topics. [mailto:ADVANCED- > > [email protected]] On Behalf Of Frans Bouma > > Sent: Monday, 06 April 2009 19:57 > > To: [email protected] > > Subject: Re: [ADVANCED-DOTNET] Creating a "public only" constructor > > > > Dean, > > > > I have the feeling the concern whether OTHER objects are created on > > the > same > > server is not the concern of the class you want to instantiate but the > > concern of a repository or other object. I know you're facing a large > > pile of code, but you have to make a change somewhere anyway. I'd > > factor out > this > > concern from this class and create factories to produce the proper > instances > > on the right server/service. > > > > FB > > > > > Hmm - yeah. Not a bad idea... but would mean that only the Business > > Services > > > layer would ever compile in that release, and everything else would > fail. > > > > > > -----Original Message----- > > > From: Discussion of advanced .NET topics. [mailto:ADVANCED- > > > [email protected]] On Behalf Of Dave Jones > > > Sent: Monday, 06 April 2009 19:31 > > > To: [email protected] > > > Subject: Re: [ADVANCED-DOTNET] Creating a "public only" constructor > > > > > > Wrap the constructor in a #if release? Then it won't be available in > > > debug? > > > > > > Dave > > > > > > > > > > > > > > > -----Original Message----- > > > From: Dean Cleaver <[email protected]> > > > > > > Date: Mon, 6 Apr 2009 16:02:43 > > > To: <[email protected]> > > > Subject: Re: [ADVANCED-DOTNET] Creating a "public only" constructor > > > > > > > > > The second constructor allows you to create a business services > > > object on > > a > > > different connection to the default - so I can specifically create > > business > > > services objects connected to 2 different servers from within the > > > same application. I then want to ensure that if I create an Invoice > > > object on a given server, than any InvoiceItems it creates are on > > > the same server, > > which > > > would be done by using the second constructor. If a developer > > > accidentally uses the default constructor, it could make a mess of > > > the > > system. > > > > > > -----Original Message----- > > > From: Discussion of advanced .NET topics. [mailto:ADVANCED- > > > [email protected]] On Behalf Of Shawn Wildermuth > > > Sent: Monday, 06 April 2009 15:55 > > > To: [email protected] > > > Subject: Re: [ADVANCED-DOTNET] Creating a "public only" constructor > > > > > > I don't think you can. Can you explain why you want to protect it > > > from internal classes? > > > > > > Thanks, > > > > > > Shawn Wildermuth > > > http://wildermuth.com > > > https://agilitrain.com > > > Microsoft MVP (C#), MCSD.NET, Author and Speaker > > > > > > The Silverlight Tour is coming to a city near you! > > > > > > > > > -----Original Message----- > > > From: Discussion of advanced .NET topics. > > > [mailto:[email protected]] On Behalf Of Dean > > > Cleaver > > > Sent: Sunday, April 05, 2009 11:42 PM > > > To: [email protected] > > > Subject: [ADVANCED-DOTNET] Creating a "public only" constructor > > > > > > Hey, anyone know if you can do this with attributes or something? I > > > want > > to > > > have 2 public constructors: > > > > > > public ClassName() > > > { > > > } > > > > > > public ClassName(some param) > > > { > > > } > > > > > > I want both publically accessible, but I want the default one > > *inaccessible* > > > internally. Can that be done? > > > > > > Dino > > > > > > =================================== > > > View archives and manage your subscription(s) at > > > http://peach.ease.lsoft.com/archives > > > > > > =================================== > > > View archives and manage your subscription(s) at > > > http://peach.ease.lsoft.com/archives > > > > > > =================================== > > > View archives and manage your subscription(s) at > > > http://peach.ease.lsoft.com/archives > > > > > > =================================== > > > View archives and manage your subscription(s) at > > > http://peach.ease.lsoft.com/archives > > > > =================================== > > View archives and manage your subscription(s) at > > http://peach.ease.lsoft.com/archives > > > > =================================== > > View archives and manage your subscription(s) at > > http://peach.ease.lsoft.com/archives > > =================================== > View archives and manage your subscription(s) at > http://peach.ease.lsoft.com/archives > > =================================== > View archives and manage your subscription(s) at > http://peach.ease.lsoft.com/archives =================================== View archives and manage your subscription(s) at http://peach.ease.lsoft.com/archives