Joe,
I would recommend a Singleton pattern as Herfried suggested. The "problem"
your going to have is where to put the singleton. Ideally you would make
Base the Singleton, however that makes it difficult for the derived classes
to override implementation. You could make the derived classes the
singleton, however then your program is 'hard coded' to the derived class.
The approach I would consider is to make Base the Singleton, however I would
store the class name to use in the app.config file. When the base creates
the instance of the singleton, it would get the class out of the app.config.
Effectively combining the Singleton Pattern with a PlugIn pattern.
http://www.yoda.arachsys.com/csharp/singleton.html http://www.martinfowler.com/eaaCatalog/plugin.html
Something like:
Imports System.Configuration
Public MustInherit Class Base
#Region " Singleton support "
Private Shared m_instance As Base
Public Shared Readonly Property Instance() As Base
Get
If m_instance is Nothing Then
Dim s As String =
ConfigurationSettings.AppSettings("base.type")
Dim t As Type = Type.GetType(s)
m_instance =
DirectCast(Activator.CreateInstance(t,True), Base)
End If
Return m_Instance
End Get
End Property
Protected Sub New()
End Sub
#End Region
Public Function DoSomething(ByVal Source As String) As String
End Function
Public MustOverride Function DoSomethingElse(ByVal Source As String)
As String
Public MustOverride Function IWroteThis(ByVal Source As String) As
String
End Class
Public MustInherit Class GeneratedStuff
Inherits Base
Protected Sub New()
End Sub
Public Overrides Function DoSomethingElse(ByVal Source As String) As
String
End Function
End Class
Public Class HandCodedStuff
Inherits GeneratedStuff
Protected Sub New()
End Sub
Public Overrides Function IWroteThis(ByVal Source As String) As
String
End Function
End Class
Public Class FinalLevel
Inherits HandCodedStuff
Protected Sub New()
End Sub
Public Overrides Function DoSomethingElse(ByVal Source As String) As
String
End Function
End Class
' The app.config file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="base.type" value="myproject.FinalLevel, myproject" />
</appSettings>
</configuration>
Then when you need to use the instance you simply use:
Dim source As String
Base.Instance.DoSomething(source)
Base.Instance.IWroteThis(source)
Base.Instance.DoSomethingElse(source)
Note the type in the config file should be in the format
"mynamespace.myclass, myassembly", where myclass is the class name you are
using, mynamespace is the namespace that class belongs to, and myassembly is
the assembly where the class is. Normally you can get the namespace &
assembly from the Project Properties. In the above case myclass can be
either FinalLevel or HandCodedStuff.
Note: The True in "Activator.CreateInstance(t,True)", allows non public
constructors to be used, this allows you to add the protected constructors
preventing the class from being created outside of the singleton pattern.
If the above is included in a class library assembly, I would define a
custom section for app.config file. Each app that used the class library
would then need to include the custom section in their app.config. This
allows better isolation for the class library settings verses the
application settings.
Public Shared ReadOnly Property Instance() As Base
Get
If m_instance Is Nothing Then
Dim col As IDictionary =
DirectCast(ConfigurationSettings.GetConfig("myproj ectSettings"),
IDictionary)
Dim s As String = DirectCast(col("type"), String)
Dim t As Type = Type.GetType(s)
m_instance = DirectCast(Activator.CreateInstance(t, True),
Base)
End If
Return m_instance
End Get
End Property
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="myprojectSettings"
type="System.Configuration.SingleTagSectionHandler " />
</configSections>
<appSettings>
</appSettings>
<myprojectSettings type="FunWithButtons.FinalLevel,
Fun.With.Buttons" />
</configuration>
The thing I like about the custom configuration section is you can give more
meaningful names, such as the assembly name & "type" for the value.
Hope this helps
Jay
"Joe Fallon" <jf******@nospamtwcny.rr.com> wrote in message
news:%2****************@TK2MSFTNGP11.phx.gbl...
1. I have a Base class that has a certain amount of functionality.
2. Then I have a CodeSmith generated class that inherits from the Base
class and adds functionality.
3. Since I want to be able to re-generate the classes on level 2 I have a
3rd level that inherits from them and implements specific hand coded
methods.
4. My colleague asked me to create a 4th level class that inherits the 3rd
level class so he can write custom functionality that overrides the
"plain" functionality at all levels above it.
I have 1-3 implemented as Shared methods.
To me, this enables simpler UI code.
For example:
strSQL = Level3ClassName.Select
In this way I do not need to instantiate an instance of the class I just
use the shared methods in levels 1-3.
================================================== =========
My problem (other than being new and not really understanding this well
enough yet <g> )
is I don't know how to implement Level 4 in a way that allows me to use
Shared methods in levels1-3 and yet Override them in Level 4.
Is it not possible?
================================================== ============
If I have to change Levels 1-3 what would you recommend?
================================================
Sample code:
Level 1
Public MustInherit Class Base
Public Shared Function DoSomething(ByVal Source As String) As String
End Function
================================================
Level 2
Public MustInherit Class GeneratedStuff
Inherits Base
Public Shared Function DoSomethingElse(ByVal Source As String) As String
End Function
================================================
Level 3
Public MustInherit Class HandCodedStuff
Inherits GeneratedStuff
Public Shared Function IWroteThis(ByVal Source As String) As String
End Function
================================================
Level 4 (implements same functionality as Level 3 but also allows
customized changes by overriding methods or creating new ones that are specific to a
single client. Level 3 functionality is for all clients.)
Public MustInherit Class FinalLevel
Inherits HandCodedStuff
Overrides Function DoSomethingElse(ByVal Source As String) As String
End Function
Thanks for any advice!
--
Joe Fallon