I have an abstract Catalog class as follows. It has a static method OpenCatalog() which is used to return a specific concrete catalog based on the type of location provided. Once it has determined the type of catalog it then calls a specific OpenCatalog() method of the correct concrete catalog type. For example I may have an implementation of Catalog that is stored in a SQL database, or another which is stored in a file system. See the code below.
public abstract class Catalog
{
public static ICatalog OpenCatalog(string location, bool openReadOnly)
{
if(location is filePath)
{
return FileSystemCatalog.OpenCatalog(string location, bool openReadOnly);
}
else if(location is SQL server)
{
return SqlCatalog.OpenCatalog(string location, bool openReadOnly);
}
else
{
throw new ArgumentException("Unknown catalog type","location");
}
}
...
}
public abstract class FileSystemCatalog:Catalog
{
public static new ICatalog OpenCatalog(string location, bool openReadOnly)
{
//Deserializes and returns a catalog from the file system at the specified location
}
...
}
public abstract class SqlCatalog:Catalog
{
public static new ICatalog OpenCatalog(string location, bool openReadOnly)
{
//creates an returns an instances of a SqlCatalog linked to a database
//at the provided location
}
...
}
First in general is it ok to hide a static method? I know it's possible to do, but it also just seems like something that one shouldn't do very often. Also is this a valid example where it's ok to hide a static method, or is there a better way to do what I'm trying to do?
It looks like you are trying to create an abstract factory in a very awkward manner. What actually happens is you are violationg Single Responsibility Principle and mixing the catalog creation concern with the catalog concern. What you need to do is to make CatalogFactory non-static class. This gives you the flexibility to whatever you please later on (eg Dependency Injection).
public class CatalogFactory {
public ICatalog CreateCatalog(string location, bool openReadOnly)
{
if(location is filePath)
{
return OpenFileCatalog(string location, bool openReadOnly);
}
else if(location is SQL server)
{
return OpenSqlCatalog(string location, bool openReadOnly);
}
else
{
throw new ArgumentException("Unknown catalog type","location");
}
}
FileSystemCatalog OpenFileCatalog(string location, bool openReadOnly) {
return new FileSystemCatalog{/*init*/};
}
SqlCatalog OpenSqlCatalog(string location, bool openReadOnly) {
return new SqlCatalog{/*init*/};
}
}
You aren't really hiding it because you can always do
Catalog.OpenCatalog(...);
If you want the base class version. In fact, static methods are associated with a specific class and aren't virtual. It's just a nice convenience that you can call static methods defined in a base class on the derived class.
I have never found an argument against the use of private/internal static methods in terms of "code smell".
A good practical example might be an extension method inside some sort of service/utility library that you want to only extend within that library.
internal static ShippingRateType ToShippingRateType(this ProviderShippingRateType rateType) { }
Related
I'd like to be able to specify an Action<string> at the app level that my library could then use for progress reporting. ConfigurationManager.AppSettings only allows XmlSerializeables, and Actions are not that.
The motivation is that console apps might just write to the console, webapps perhaps to a trace, and forms perhaps to files or a particular field, the point is the app should be able to configure it imo.
My approach currently is to have in the library a LibSettings class that has a static settable Action<string>. That means anyone can set it elsewhere too, which poses potential for bugs.
At first I thought maybe a static constructor (with parameters) would do but it turns out you can't call static constructors explicitly and you certainly can't give them parameters.
Is there any way to achieve my goal of being able to specify the Feedback action once and only onc in some sort of custom app settings, and not throw a runtime exception on second setting, or swallow the second setting? That is essentially like a singleton property of my design when I design it. Thanks in advance.
Serializing and deserializing a delegate usually isn't a good idea, as it easily leads to pretty serious security concerns (see arbitrary code execution).
Instead I would recommend having a enum or similar serializable type that identifies a number of statically defined functions and convert between them. Something like this:
public enum FeedbackAction
{
Console,
Trace,
...
}
public static class FeedbackActions
{
public static void Console(string text) { ... }
public static void Trace(string text) { ... }
public static Action<string> GetAction(FeedbackAction action)
{
switch (action)
{
case FeedbackAction.Console:
return Console;
case FeedbackAction.Trace:
return Trace;
default:
throw new ArgumentException("Invalid feedback action.", nameof(action));
}
}
}
Now whenever you're trying to use the app setting, just call FeedbackActions.GetAction to convert between your enum values and the appropriate Action<string>.
For example:
public static class Feedback
{
public static Action<string> feedbackAction;
public static object syncLock = new object();
public static void ProvideFeedback(string text)
{
if (feedbackAction == null)
{
// synchronize to avoid duplicate calls
lock (syncLock)
{
if (feedbackAction == null)
{
var value = ConfigurationManager.AppSettings["FeedbackAction"];
feedbackAction = FeedbackActions.GetAction(value);
}
}
}
feedbackAction(text);
}
}
This way you can safely call Feedback.ProvideFeedback, and its behavior will be driven by the app/web.config file.
If you need to make a solution that's flexible enough to handle almost any feedback action, I'd strongly recommend reading up on inversion of control in general and the Managed Extensibility Framework (MEF) in particular. A full implementation would be a bit too complex to provide here, but in general it would look a bit like this:
public interface IFeedbackAction
{
void ProvideFeedback(string text);
}
public interface IFeedbackMetadata
{
string Name { get; }
}
[Export(typeof(IFeedbackAction)), ExportMetadata("Name", "Console")]
public interface ConsoleFeedbackAction : IFeedbackAction { ... }
[Export(typeof(IFeedbackAction)), ExportMetadata("Name", "Trace")]
public interface TraceFeedbackAction : IFeedbackAction { ... }
public static class Feedback
{
[ImportMany]
public IEnumerable<Lazy<IFeedbackAction, IFeedbackMetadata>> FeedbackActions { get; set; }
private IFeedbackAction feedbackAction;
public static void ProvideFeedback(string text)
{
if (feedbackAction == null)
{
// synchronize to avoid duplicate calls
lock (syncLock)
{
if (feedbackAction == null)
{
var value = ConfigurationManager.AppSettings["FeedbackAction"];
feedbackAction = GetFeedbackAction(value);
}
}
}
feedbackAction.ProvideFeedback(text);
}
private static IFeedbackAction GetFeedbackAction(string name)
{
return FeedbackActions
.First(l => l.Metadata.Name.Equals(name)).Value;
}
}
With this method, consumers would be able to provide their own implementation of IFeedbackAction, decorated with the appropriate [Export] and [ExportMetadata] attributes, and simply specify use of their custom actions in the app/web.config file.
Ok, let's see if I inderstood all right.
Let's suppose this is your config class:
public static class LibSettings
{
public static readonly Action<string> TheAction{ get; private set; }
static LibSettings()
{
var action = ConfigurationManager.AppSettings["libAction"];
switch(action)
{
case "console":
TheAction = ConsoleAction;
break;
case "web":
TheAction = WebAction;
break;
//And as many as you need...
}
}
private static void ConsoleAction(string Parameter)
{
//Whatever it does...
}
private static void WebAction(string Parameter)
{
//Whatever it does...
}
}
Is this what you meant? it will be only set once whenever you access any property of the class, it cannot be modified externally and will change the Action upon an AppSeting record.
Ok, let's go with another approach. Now we will have two classes a temporal holder where you will set the action you want and the current settings class.
public static class TemporalHolder
{
public static Action<string> HeldAction{ get; set; }
}
public static class LibSettings
{
public static readonly Action<string> TheAction;
static LibSettings()
{
TheAction = TemporalHolder.HeldAction;
}
public static void Init()
{
/*Just do nothing as we will use it to fire the constructor*/
}
}
And now, to use it, just seth the action to the temporal holder and call anithing static on LibSettings:
TemporalHolder.Action = (your function);
LibSettings.Init();
And voila! no errors on second settings, it cannot be changed on runtime and cannot be reasigned. are all the conditions met?
I have a third party C# library for ldap operations. It does all operations on connection object as below:
LdapConnection connection = new LdapConnetion(Settings settings);
connection.Search(searchOU, filter,...);
which I feel is not readable. I want to write a wrapper around it so that I should be able to write code like below:
As I would like to have different Ldap classes like
public class AD: LdapServer { }
public class OpenLdap: LdapServer { }
and then
AD myldap = new AD(Settings settings);
myldap.Users.Search(searchOU, filter,...)
myldap.Users.Add(searchOU, filter,...)
myldap.Users.Delete(searchOU, filter,...)
I am thinking about Proxy design pattern, but things are not getting into my head about hot to go about it. What classes should I have etc.
Any help?
The solution posted above inherits from the LdapConnection. This is good if you want to maintain the inheritance chain, but I dont think that is necessary in your case. You simply want to customize and simplify the interface.
The proxy design pattern inherits from the underlying object so that the proxy object can be used anywhere that the underlying object is required, this is good if you want to "inject" extra functionality into the class without the clients of that class realising. I dont think this is your intention here?
The big problem with the solution posted above is that (because it inherits directly from LdapConnection) you can call search in two ways like so:
Settings settings = new Settings();
AD myAD = new AD(settings);
object results = myAD.Users.Search();
// OR
object results2 = myAD.Search();
As I'm sure you can see from the code, both of these call the exact same underlying method. But in my opinion, this is even more confusing to developers than just using the vanilla LdapConnection object. I would always be thinking "whats the difference between these seemingly identical methods??" Even worse, if you add some custom code inside the UsersWrapper Search method, you cannot always guarentee that it will be called. The possibility will always exist for a developer to call Search directly without going through the UsersWrapper.
Fowler in his book PoEAA defines a pattern called Gateway. This is a way to simplify and customize the interface to an external system or library.
public class AD
{
private LdapConnection ldapConn;
private UsersWrapper users;
public AD()
{
this.ldapConn = new LdapConnection(new Settings(/* configure settings here*/));
this.users = new UsersWrapper(this.ldapConn);
}
public UsersWrapper Users
{
get
{
return this.users;
}
}
public class UsersWrapper
{
private LdapConnection ldapConn;
public UsersWrapper(LdapConnection ldapConn)
{
this.ldapConn = ldapConn;
}
public object Search()
{
return this.ldapConn.Search();
}
public void Add(object something)
{
this.ldapConn.Add(something);
}
public void Delete(object something)
{
this.ldapConn.Delete(something);
}
}
}
This can then be used like so:
AD myAD = new AD();
object results = myAD.Users.Search();
Here you can see that the LdapConnection object is completly encapsulated inside the class and there is only one way to call each method. Even better, the setting up of the LdapConnection is also completely encapsulated. The code using this class doesn't have to worry about how to set it up. The settings are only defined in one place (in this class, instead of spread throughout your application).
The only disadvantage is that you loose the inheritance chain back to LdapConnection, but I dont think this is necessary in your case.
Ok, if you simply want to split the methods up into they objects that they act on (i.e. in your example add the .Users. before the method call) you can do something similar to this.. You'll need to get the method parameters and return types correct for your library, I've just used object here.
Is this the sort of thing you're looking for?
public class AD : LdapConnection
{
private UsersWrapper users;
public AD(Settings settings) : base(settings)
{
this.users = new UsersWrapper(this);
}
public UsersWrapper Users
{
get
{
return this.users;
}
}
public class UsersWrapper
{
private AD parent;
public UsersWrapper(AD parent)
{
this.parent = parent;
}
public object Search()
{
return this.parent.Search();
}
public void Add(object something)
{
this.parent.Add(something);
}
public void Delete(object something)
{
this.parent.Delete(something);
}
}
}
This can then be be used as follows:
Settings settings = new Settings();
AD myAD = new AD(settings);
object results = myAD.Users.Search();
Remember that this isn't strictly a "wrapper" because it actually inherits from the underlying class.
public abstract class AbstractDBConnector
{
private AdServiceDB db;
public AdServiceDB Adapter
{
get
{
if (db == null) db = new AdServiceDB();
return db;
}
}
}
and a class that inherits from it:
public class BaseDataValidator : AbstractDBConnector
{
public static bool Check()
{
var t = Adapter.Users.Where(x=>x.Id<10).ToList(); //the error is here
return true; //example
}
}
this code obviously generates an error: An object reference is required for the non-static field, method, or property Is it even possible to do a trick to use the Adapter in the static method ?
Only if Adapter is also static, which you probably don't want it to be (but maybe you do, I'm not sure what the exact use case is, there's not enough info). Pass the adapter to the method as a parameter if the method must be static, but it seems more likely that your method just shouldn't be static in the first place.
EDIT: note that for the "make it static approach to work you'll have to make both Adapter and db static.
Let's say we have the following piece of code:
public class Event { }
public class SportEvent1 : Event { }
public class SportEvent2 : Event { }
public class MedicalEvent1 : Event { }
public class MedicalEvent2 : Event { }
public interface IEventFactory
{
bool AcceptsInputString(string inputString);
Event CreateEvent(string inputString);
}
public class EventFactory
{
private List<IEventFactory> factories = new List<IEventFactory>();
public void AddFactory(IEventFactory factory)
{
factories.Add(factory);
}
//I don't see a point in defining a RemoveFactory() so I won't.
public Event CreateEvent(string inputString)
{
try
{
//iterate through all factories. If one and only one of them accepts
//the string, generate the event. Otherwise, throw an exception.
return factories.Single(factory => factory.AcceptsInputString(inputString)).CreateEvent(inputString);
}
catch (InvalidOperationException e)
{
throw new InvalidOperationException("Either there was no valid factory avaliable or there was more than one for the specified kind of Event.", e);
}
}
}
public class SportEvent1Factory : IEventFactory
{
public bool AcceptsInputString(string inputString)
{
return inputString.StartsWith("SportEvent1");
}
public Event CreateEvent(string inputString)
{
return new SportEvent1();
}
}
public class MedicalEvent1Factory : IEventFactory
{
public bool AcceptsInputString(string inputString)
{
return inputString.StartsWith("MedicalEvent1");
}
public Event CreateEvent(string inputString)
{
return new MedicalEvent1();
}
}
And here is the code that runs it:
static void Main(string[] args)
{
EventFactory medicalEventFactory = new EventFactory();
medicalEventFactory.AddFactory(new MedicalEvent1Factory());
medicalEventFactory.AddFactory(new MedicalEvent2Factory());
EventFactory sportsEventFactory = new EventFactory();
sportsEventFactory.AddFactory(new SportEvent1Factory());
sportsEventFactory.AddFactory(new SportEvent2Factory());
}
I have a couple of questions:
Instead of having to add factories
here in the main method of my
application, should I try to
redesign my EventFactory class so it
is an abstract factory? It'd be
better if I had a way of not having
to manually add
EventFactories every time I want to
use them. So I could just instantiate MedicalFactory and SportsFactory. Should I make a Factory of factories? Maybe that'd be over-engineering?
As you have probably noticed, I am using a inputString string as argument to feed the factories. I have an application that lets the user create his own events but also to load/save them from text files. Later, I might want to add other kinds of files, XML, sql connections, whatever. The only way I can think of that would allow me to make this work is having an internal format (I choose a string, as it's easy to understand). How would you make this? I assume this is a recurrent situation, probably most of you know of any other more intelligent approach to this. I am then only looping in the EventFactory for all the factories in its list to check if any of them accepts the input string. If one does, then it asks it to generate the Event.
If you find there is something wrong or awkward with the method I'm using to make this happen, I'd be happy to hear about different implementations. Thanks!
PS: Although I don't show it in here, all the different kind of events have different properties, so I have to generate them with different arguments (SportEvent1 might have SportName and Duration properties, that have to be put in the inputString as argument).
I am not sure about the input string question but for the first question you can likely use "convention over configuration"; a combination of reflection, the IEventFActory type and the naming you already have in place, Name.EndsWith("EventFactory") should allow you to instantiate the factories and get them into their Lists with code.
HTH ,
Berryl
I'm sure this must be a common problem. I've got a class that in an ideal world would have the following constructors
public Thing(string connectionString)
public Thing(string fileName)
Obviously this isn't allowed because the signatures are the same. Does anybody know of an elegant solution to this problem?
You can used the named constructor idiom:
public class Thing
{
private string connectionString;
private string filename;
private Thing()
{
/* Make this private to clear things up */
}
public static Thing WithConnection(string connectionString)
{
var thing = new Thing();
thing.connectionString = connectionString;
return thing;
}
public static Thing WithFilename(string filename)
{
var thing = new Thing();
thing.filename = filename;
return thing;
}
}
Well, there are several potentials - what's considered elegent depends on the usage scenario.
Static factory methods, that call into a private constructor.
static Thing thingWithFileName(string fileName)
Create a different type for one of the parameters, or use a builtin. Rather than a string fileName, you could use a System.IO.FileStream. This is also more type safe, as I can't accidently pass the wrong data into the wrong static method, or field.
Pass a second parameter to the constructor, either an enum or a boolean, indicating the intent of the first parameter
enum ThingType { FileName, ConnectionString }
Thing(string str, ThingType type) ...
Subclass Thing, so you have a ConnectionTypeThing and a FileBackedThing
Completely eliminate Thing doing it's connection, and have preconnected data sources provided. So you end up with
Thing(InputStream dataSource)
or something analogous.
My "elegance" money goes on either the first or second suggestions, but I'd need more context to be happy with any choice.
You can make all the constructors private and create factory methods (static methods on the class like CreateFromConnectionString()).
These actually seem like different "things" to me, either a class associated with a file or a class associated with a database. I'd define an interface, then have separate implementations for each. Use a Factory to generate the correct implementation.
A hint that you may need to change your design is if your methods have to decide whether they are working with a file or a database before they perform the required action. If this is the case, then separating into different classes would be the way I would go.
public interface IThing
{
... methods to do the things that Things do
}
public class FileThing : IThing
{
... file-based methods
}
public class DatabaseThing : IThing
{
... database-based methods
}
public static class ThingFactory
{
public IThing GetFileThing( string name )
{
return new FileThing( name );
}
public IThing GetDatabaseThing( string connectionString )
{
return new DatabaseThing( connectionString );
}
}
If you had common behavior you could alternatively define an abstract class containing the default/common behavior and derive from it instead of/in addition to the interface.
Make two public properties ConnectionString and FileName and then use these to fill your object.
In C# you can use an object initalizer. Like this:
Thing thing = new Thing{FileName = "abc", ConnectionString = "123"};
Here are some workarounds.
Have one constructor that takes a connection string, and then have a factory method on the class that takes filename. Something like this:
public static Thing CreateThing(string fileName)
this method can call a private parameter less constructor, and you can take it from there.
Another option, is to have an enum that has two types in it. FileName and ConnectionString. Then just have one constructor that takes a string, and the enum. Then based on the enum you can determine which way to go.
I like static constructor-functions:
class Thing
{
public static Thing NewConnection(string connectionString)
{
return new Thing(connectionString, true);
}
public static Thing NewFile(string fileName);
{
return new Thing(fileName, false);
}
}
.
.
.
{
var myObj = Thing.NewConnection("connect=foo");
var Obj2 = Thing.NewFile("myFile.txt");
}
(not shown, but straight-forward, the implementation of the Thing-Constructor with an extra boolean parameter).