Purpose of having API wrapped around interface - c#

I am working on a piece of C# web application that has a page (MainPage) with a small area to display a gadget. There are several kinds of gadgets implementing a main interface (IMainInterface) and an optional interface (IOptionalInterface).
In MainPage, when interacting with the gadget class, it uses following syntax:
MyAPI api = new MyAPI();
api.SomeMethod(gadgetClassName, param);
And in api.SomeMethod(...), it does following:
// use reflection to get an IMainInterface based on gadgetClassName
Type t = Type.GetType(gadgetClassName);
IMainInterface gadget = (IMainInterface)t.InvokeMember(
gadgetClassName,
BindingFlags.CreateInstance,
null,
null,
null);
return gadget.SomeMethod(param)
Looking at this MyAPI class, it contains a whole bunch of methods that map to the corresponding methods defined in IMainInterface and IOptionalInterface.
My question, is this MyAPI class really neccesary? Wouldn't it be less overhead if MainPage accesses interfaces(IMainInterface and IOptionalInterface) directly?
Update: seeing some of the answers, I realized that I wasn't explicit that the "several kinds of gadget" means different classes (e.g. CalendarGadget, TaskGadget).
Update 2: Added more code sample

The MyApi class looks like it's shielding you from using reflection to create the object, null checks if the optional interface isn't in use, and probably the whole fact of using interfaces in general. Without all the code it's conjecture. As Dzmitry Huba points out, mixing a factory and a wrapper is a bad smell, and you should try to refactor that out.
static class GadgetFactory
{
public static IMainInterface GetGadget(string className)
{
(IMainInterface)Activator.CreateInstance(Type.GetType(className))
}
}
A factory decouples the logic of creation, but it should only be responsible for creation.
Q: Is there any logic in myAPI, or is it just creating and then dispatching if the gadget supports the interface?
If MyApi doesn't have any logic, it's hard to see why it's necessary. Perhaps the writer of MyApi didn't realize at the time that you can cast to the other interface when needed. I have a hunch that they were trying to shield junior developers from interfaces.
// basic use of interfaces
IMainInterface gadget = GadgetFactory.GetGadget("Gadgets.Calendar");
gadget.SomeMethod();
IOptionalInterface optional = gadget as IOptionalInterface;
if( optional != null ) // if optional is null, the interface is not supported
optional.SomeOptionalMethod();
A relevant SO question Difference between Activator.CreateInstance() and typeof(T).InvokeMember() with BindingFlags.CreateInstance

It seems the author of MyApi mixed factory and consumer. I do not see any reason to access interface members indirectly when it is defined at compile time.

Yes, from the description in your question, I'd say reflection or any other indirection mechanism is unnecessary. I'm not sure if that answers your question though?
// in MainPage:
IList<IMainInterface> gadgets = new List<IMainInterface>
{
(IMainInterface)Activator.CreateInstance(Type.GetType("Gadgets.CalendarGadget")),
(IMainInterface)Activator.CreateInstance(Type.GetType("Gadgets.TaskGadget")),
};

Generally this is not bad. But I guess that this is complete overkill for your intentions. I would suggest to borrow something from IOC.
var api = new MyAPI(new GadgetClass());
api.SomeMethod(parameters);
This would make your life much less complicated.
Hope this helps

Related

In ReactiveUI, how to call GetService for MutableDependencyResolver

I am reading the book You, I and ReactiveUI and my question relates to the source code for the book at https://github.com/kentcb/YouIandReactiveUI. The versions of ReactiveUI and Splat have changed since the code was published and one portion of the code cannot be duplicated in the current versions. I have contacted the author and am still waiting on a response as of this time of posting this question, and so I am submitting this question here.
In App.xaml.cs there is a call to a Registrations.cs class that passes the current mutable dependency resolver:
public App()
{
this.autoSuspendHelper = new AutoSuspendHelper(this);
Registrations.Register(Splat.Locator.CurrentMutable);
}
In the Registrations.cs class, there is a line that takes that IMutableDependencyResolver and calls GetService:
public static void Register(IMutableDependencyResolver container)
{
...
var defaultViewLocator = container.GetService<IViewLocator>();
...
}
I, too, would like to get the IVewLocator service, but IMutableDependencyResolver no longer has a GetService method.
So my question is, how should this code be modified to have the same functionality?
The Splat.Locator.Current is an IReadonlyDependenyResolver and that does have a GetService method. Should that be used instead? I wasn't sure if I should change to using Splat.Locator.Current in case there was a reason that Splat.Locator.CurrentMutable was used and wanted to make sure that if I changed to using Splat.Locator.Current that it would not introduce anything unexpected.
UPDATE:
Just want to add that, armed with the knowledge from DPVreony's answer that it is typically the same class implementing the two interfaces, I was able to implement some later lines in the Registrations.cs class that I needed.
So, further in that class, there are some lines that register constants. These needed the mutable dependency resolver. So you can just pass both the read only and mutable into the Registrations class and use them where needed, as shown below:
public static void Register(IReadonlyDependencyResolver container, IMutableDependencyResolver mutableContainer)
{
...
var defaultViewLocator = container.GetService<IViewLocator>();
...
mutableContainer.RegisterConstant(viewLocator, typeof(IViewLocator));
...
var defaultActivationForViewFetcher = container.GetService<IActivationForViewFetcher>();
...
mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IActivationForViewFetcher));
mutableContainer.RegisterConstant(activationForViewFetcher, typeof(IForcibleActivationForViewFetcher));
}
And then call the method like so:
Registrations.Register(Splat.Locator.Current, Splat.Locator.CurrentMutable);
There was a change in Splat due to how some DI containers behave with registering services (i.e. they keep re-initializing). So get functionality was split off onto the IReadonlyDependenyResolver exposed by Splat.Locator.Current
It was to encourage the mindset of use the MutableLocator to get everything in place and then after that you should only ever need to read using Splat.Locator.Current so you're fine to use it. Typically it's the same class implementing the 2 interfaces, so it's a semantic change to reduce risks of tearing down the locator by mistake.
So in short yes Splat.Locator.Current is for GetService
Hope that all makes sense.

Is It Possible to Access Introduced/Weaved Interfaces and Members by PostSharp During Build Time?

I am designing a scenario where two PostSharp aspects are working with each other. I have one aspect (FirstAspect in the code below) that is meant to introduce an interface, and then another aspect (SecondAspect in the code below) is supposed to work with the interface that was introduced by the first aspect.
However, it does not seem that the interface that is introduced by the first aspect is ever available to the second aspect.
Here is the code that I am currently working with:
public class Tests
{
[Fact]
public void Verify()
{
// Not really all that significant as the current code does not compile correctly:
var sut = new MyClass();
Assert.True( sut is IInterface );
}
public interface IInterface
{
void HelloWorld();
}
[IntroduceInterface( typeof(IInterface) )]
public class FirstAspect : InstanceLevelAspect, IInterface, IAspectProvider
{
public void HelloWorld() {}
public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
{
// Implementing IAspectProvider appears to ensure this aspect is processed first.
// This may be a bug.
// Please see: http://support.sharpcrafters.com/discussions/problems/3365-runtimeinitialize-does-not-follow-ordering-rules#comment_40824072
// for more information.
yield break;
}
}
[AspectTypeDependency( AspectDependencyAction.Order, AspectDependencyPosition.After, typeof(FirstAspect) )]
public class SecondAspect : InstanceLevelAspect, IAspectProvider
{
public IEnumerable<AspectInstance> ProvideAspects( object targetElement )
{
var type = (Type)targetElement;
if ( !typeof(IInterface).GetTypeInfo().IsAssignableFrom( type ) )
{
// This is currently being thrown, as MyClass does not implement
// IInterface when the AppDomain is first loaded and initialized:
throw new InvalidOperationException( $"Does not implement {typeof(IInterface)}" );
}
// How to access the weaved elements from FirstAspect? ...
yield break;
}
}
[FirstAspect, SecondAspect]
class MyClass {}
}
When I build, the InvalidOperationException in the SecondAspect.ProvideAspects is thrown, as the interface that was introduced by FirstAspect is not available to SecondAspect at the time the call is made. That is, even though the interface has been weaved into the MyClass type, the type as it stands within the current AppDomain as loaded is not marked as having the interface implemented.
What I am looking for is the ability to access and locate all known and weaved interfaces and members on a target element during build time.
I looked into ReflectionSearch, and this is close to what I am looking for, but it does not appear to account for weaved elements at the time calls into this API are made. For instance, making a call to ReflectionSearch.GetMembersOfType does not yield the expected IInterface.HelloWorld on MyClass (which is introduced by FirstAspect in the example above).
Is there another API I should be using to access introduced/weaved elements by PostSharp during build-time? Is this even possible?
So this question looks a little old, but I have a similar issue which I still need an answer to (which is: how do I introduce an attribute to an introduced method without applying the attribute to the implementation and copying it). That said, I may have to ask my own question, as there are some common steps for the pattern you're asking about which may solve your dilemma, but do not solve mine. It looks like you've already experimented with some of this, but for the sake of others that come along, I'll detail it out.
In short, don't use "reflection" types to specify aspect dependency. PostSharp provides attributes which you can use to require aspects to be applied or to require specific order (See: Coping with Several Aspects on the Same Target for an overview), as well as a method for importing members already provided by other aspects (This StackOverflow Answer, while not marked, is the correct answer to that user's question and also shows a way to use the ImportMemberAttribute together with aspect dependency). The ImportMemberAttribute is capable of importing members from other aspects as long as the order is correct; the IsRequired property on this attribute will cause a build error if the member does not exist and was not introduced by an aspect.
Now, if you want your second aspect to be able to apply to all classes that implement an interface, whether the interface was applied by your first aspect or not, you would set the AspectTypeDependencyAttribute with AspectDependencyAction.Order, but not set an AspectTypeDependencyAttribute with AspectDependencyAction.Required; if you only want the second aspect to apply to targets advised by the first then you can apply multiple dependency attributes to specify both the requirement and the order and no Aspect Provider would be required (the above answer also shows an alternative implementation applying Advice to multiple Pointcuts in a single Aspect). Similarly, if you want your first aspect to always require your second aspect you can apply an additional AspectTypeDependencyAttribute to specify requirement in the other direction (i.e. if both require the other you want the requirement specified on both).
Aspect "Priority" can also be used to determine the order aspects are applied, although whenever possible you should use the dependencies instead because they also server as contract documentation.
This is all assuming you don't actually need to use an Aspect Provider (since your comments imply it was done for ordering). You would not want one Aspect Provider to depend on the results of another Aspect Provider (this would violate separation of concerns), you would instead have a single Aspect Provider yield multiple aspects for each target. You can, however, use AspectTypeDependencyAttribute on Aspect Providers as well so, for instance, you can have a Type Level Aspect Provider that orders after a type level aspect that introduces an interface and then in the provider you can loop through methods on the type and inject aspects that depend on the first aspect (e.g. an interface introduction follower by a provider that applies method interception advice to members that can now call methods introduced by the first aspect).
Hope that clears things up for you (or, given the time since the question was asked, anyone else that runs into this issue). Some of this information may also be outdated or inaccurate (for all I know, it may now be possible to detect injected interfaces on the target types passed to aspect providers, under some or any condition), but I believe the patterns expressed are still the preferred practice proposed by PostSharp.

Abstract Factory design pattern to create objects? Why can’t we just use the new operator?

why do we need a Abstract Factory design pattern to create objects? Why can’t we just use the new operator?
answer is, to avoid tight coupleing of the objects. But I didn't understand how ? can anyone explain with code (will be very useful).
what makes abstract factory design pattern useful and when.
Thanks in advance.
Harsha T
If you use the new operator, you have to specify which exact type you want.
Sometimes you want to be more generic, for example because you want to be able to change that instantiated type in all the codebase quickly.
An abstract factory design pattern is designed to create an object with a specific setup at initialization time. For example if you have a lot of similarly connected classes, rather than repeating the same 4+ lines [and using copying and pasting], the abstract factory would allow for you to keep the 4+ lines in a single location and reduce the amount of changes needed.
Reference For Abstract Factory
If you have :
class Foo implements DoSomething {...}
class Bar implements DoSomething {...}
obj = new Foo();
obj.doSomething();
Everywhere in your code, once you want to change all instances of Foo to use instances of Bar, are you really going to do search/replace ?
If you have :
obj = DoSomethingFactory.create();
obj.doSomething();
Inside the DoSomethingFactory, you can return any object you want that implements the DoSomething interface.
By using a Factory, you have the control over all the objects that are created by it.
If you decide to change the way the Factory creates objects, the changes take effect immediately in the code that uses the Factory.
Here's a simple example derived from a version independence layer I built for our product:
interface ICadSystemFactory
{
ICadSystem GetSystemInstance();
}
class 3dCadSystemVersion1 : ICadSystemFactory
{
ICadSystem GetSystemInstance()
{
return new 3dCadSystemWrapperVersion1(new 3dCadSystemVersion1());
}
}
class 3dCadSystemVersion2 : ICadSystemFactory
{
ICadSystem GetSystemInstance()
{
return new 3dCadSystemWrapperVersion2(new 3dCadSystemVersion2());
}
}
Where the 3dCadSystemWrapperVersionX objects implement the ICadSystem interface. I use a Registry object to decide what base factory I want to create based on certain version identifiers. This allows me to plug in new versions as needed without disturbing the existing infrastructure, which turns out to be useful in this case. It would, in fact, allow me to plug in whole new products if I needed to, which could generally be useful but in my case isn't worth the implementation effort.
There's a rather good C# example on Wikipedia. It keeps your application-level code from having to know which implementations it's getting. The factory takes care of it.
Using an abstract factory, you can create objects without knowledge of the actual type. Let's say you need a IDictionary. You could either create a new instance of a binary-tree-class that you happen to know, or you could tell the IDictionary-factory that you need a new instance. Then someone else could create a factory implementation that returns hash-tables, but everything on your side will still work the same way.
first of all you don't need to know the specific type of object your factory is instantiating,
then you can plug your factory classes around your project letting them instantiating objects for your components without having to use new in your code. The factory already do its dirty work
it conceptually separates the instantiation of object from their usage, keeping things decoupled

Good Case For Interfaces

I work at a company where some require justification for the use of an Interface in our code (Visual Studio C# 3.5).
I would like to ask for an Iron Clad reasoning that interfaces are required for. (My goal is to PROVE that interfaces are a normal part of programming.)
I don't need convincing, I just need a good argument to use in the convincing of others.
The kind of argument I am looking for is fact based, not comparison based (ie "because the .NET library uses them" is comparison based.)
The argument against them is thus: If a class is properly setup (with its public and private members) then an interface is just extra overhead because those that use the class are restricted to public members. If you need to have an interface that is implemented by more than 1 class then just setup inheritance/polymorphism.
Code decoupling. By programming to interfaces you decouple the code using the interface from the code implementing the interface. This allows you to change the implementation without having to refactor all of the code using it. This works in conjunction with inheritance/polymorphism, allowing you to use any of a number of possible implementations interchangeably.
Mocking and unit testing. Mocking frameworks are most easily used when the methods are virtual, which you get by default with interfaces. This is actually the biggest reason why I create interfaces.
Defining behavior that may apply to many different classes that allows them to be used interchangeably, even when there isn't a relationship (other than the defined behavior) between the classes. For example, a Horse and a Bicycle class may both have a Ride method. You can define an interface IRideable that defines the Ride behavior and any class that uses this behavior can use either a Horse or Bicycle object without forcing an unnatural inheritance between them.
The argument against them is thus: If
a class is properly setup (with its
public and private members) then an
interface is just extra overhead
because those that use the class are
restricted to public members. If you
need to have an interface that is
implemented by more than 1 class then
just setup inheritance/polymorphism.
Consider the following code:
interface ICrushable
{
void Crush();
}
public class Vehicle
{
}
public class Animal
{
}
public class Car : Vehicle, ICrushable
{
public void Crush()
{
Console.WriteLine( "Crrrrrassssh" );
}
}
public class Gorilla : Animal, ICrushable
{
public void Crush()
{
Console.WriteLine( "Sqqqquuuuish" );
}
}
Does it make any sense at all to establish a class hierarchy that relates Animals to Vehicles even though both can be crushed by my giant crushing machine? No.
In addition to things explained in other answers, interfaces allow you simulate multiple inheritance in .NET which otherwise is not allowed.
Alas as someone said
Technology is dominated by two types of people: those who understand what they do not manage, and those who manage what they do not understand.
To enable unit testing of the class.
To track dependencies efficiently (if the interface isn't checked out and touched, only the semantics of the class can possibly have changed).
Because there is no runtime overhead.
To enable dependency injection.
...and perhaps because it's friggin' 2009, not the 70's, and modern language designers actually have a clue about what they are doing?
Not that interfaces should be thrown at every class interface: just those which are central to the system, and which are likely to experience significant change and/or extension.
Interfaces and abstract classes model different things. You derive from a class when you have an isA relationship so the base class models something concrete. You implement an interface when your class can perform a specific set of tasks.
Think of something that's Serializable, it doesn't really make sense (from a design/modelling point of view) to have a base class called Serializable as it doesn't make sense to say something isA Serializable. Having something implement a Serializable interface makes more sense as saying 'this is something the class can do, not what the class is'
Interfaces are not 'required for' at all, it's a design decision. I think you need to convince yourself, why, on a case-by-case basis, it is beneficial to use an interface, because there IS an overhead in adding an interface. On the other hand, to counter the argument against interfaces because you can 'simply' use inheritance: inheritance has its draw backs, one of them is that - at least in C# and Java - you can only use inheritance once(single inheritance); but the second - and maybe more important - is that, inheritance requires you to understand the workings of not only the parent class, but all of the ancestor classes, which makes extension harder but also more brittle, because a change in the parent class' implementation could easily break the subclasses. This is the crux of the "composition over inheritance" argument that the GOF book taught us.
You've been given a set of guidelines that your bosses have thought appropriate for your workplace and problem domain. So to be persuasive about changing those guidelines, it's not about proving that interfaces are a good thing in general, it's about proving that you need them in your workplace.
How do you prove that you need interfaces in the code you write in your workplace? By finding a place in your actual codebase (not in some code from somebody else's product, and certainly not in some toy example about Duck implementing the makeNoise method in IAnimal) where an interface-based solution is better than an inheritance-based solution. Show your bosses the problem you're facing, and ask whether it makes sense to modify the guidelines to accommodate situations like that. It's a teachable moment where everyone is looking at the same facts instead of hitting each other over the head with generalities and speculations.
The guideline seems to be driven by a concern about avoiding overengineering and premature generalisation. So if you make an argument along the lines of we should have an interface here just in case in future we have to..., it's well-intentioned, but for your bosses it sets off the same over-engineering alarm bells that motivated the guideline in the first place.
Wait until there's a good objective case for it, that goes both for the programming techniques you use in production code and for the things you start arguments with your managers about.
Test Driven Development
Unit Testing
Without interfaces producing decoupled code would be a pain. Best practice is to code against an interface rather than a concrete implementation. Interfaces seem rubbish at first but once you discover the benefits you'll always use them.
You can implement multiple interfaces. You cannot inherit from multiple classes.
..that's it. The points others are making about code decoupling and test-driven development don't get to the crux of the matter because you can do those things with abstract classes too.
Interfaces allow you to declare a concept that can be shared amongst many types (IEnumerable) while allowing each of those types to have its own inheritance hierarchy.
In this case, what we're saying is "this thing can be enumerated, but that is not its single defining characteristic".
Interfaces allow you to make the minimum amount of decisions necessary when defining the capabilities of the implementer. When you create a class instead of an interface, you have already declared that your concept is class-only and not usable for structs. You also make other decisions when declaring members in a class, such as visibility and virtuality.
For example, you can make an abstract class with all public abstract members, and that is pretty close to an interface, but you have declared that concept as overridable in all child classes, whereas you wouldn't have to have made that decision if you used an interface.
They also make unit testing easier, but I don't believe that is a strong argument, since you can build a system without unit tests (not recommended).
If your shop is performing automated testing, interfaces are a great boon to dependency injection and being able to test a unit of software in isolation.
The problem with the inheritance argument is that you'll either have a gigantic god class or a hierarchy so deep, it'll make your head spin. On top of that, you'll end up with methods on a class you don't need or don't make any sense.
I see a lot of "no multiple inheritance" and while that's true, it probably won't phase your team because you can have multiple levels of inheritance to get what they'd want.
An IDisposable implementation comes to mind. Your team would put a Dispose method on the Object class and let it propagate through the system whether or not it made sense for an object or not.
An interface declares a contract that any object implementing it will adhere to. This makes ensuring quality in code so much easier than trying to enforce written (not code) or verbal structure, the moment a class is decorated with the interface reference the requirements/contract is clear and the code won't compile till you've implemented that interface completely and type-safe.
There are many other great reasons for using Interfaces (listed here) but probably don't resonate with management quite as well as a good, old-fashioned 'quality' statement ;)
Well, my 1st reaction is that if you've to explain why you need interfaces, it's a uphill battle anyways :)
that being said, other than all the reasons mentioned above, interfaces are the only way for loosely coupled programming, n-tier architectures where you need to update/replace components on the fly etc. - in personal experience however that was too esoteric a concept for the head of architecture team with the result that we lived in dll hell - in the .net world no-less !
Please forgive me for the pseudo code in advance!
Read up on SOLID principles. There are a few reasons in the SOLID principles for using Interfaces. Interfaces allow you to decouple your dependancies on implementation. You can take this a step further by using a tool like StructureMap to really make the coupling melt away.
Where you might be used to
Widget widget1 = new Widget;
This specifically says that you want to create a new instance of Widget. However if you do this inside of a method of another object you are now saying that the other object is directly dependent on the use of Widget. So we could then say something like
public class AnotherObject
{
public void SomeMethod(Widget widget1)
{
//..do something with widget1
}
}
We are still tied to the use of Widget here. But at least this is more testable in that we can inject the implementation of Widget into SomeMethod. Now if we were to use an Interface instead we could further decouple things.
public class AnotherObject
{
public void SomeMethod(IWidget widget1)
{
//..do something with widget1
}
}
Notice that we are now not requiring a specific implementation of Widget but instead we are asking for anything that conforms to IWidget interface. This means that anything could be injected which means that in the day to day use of the code we could inject an actual implementation of Widget. But this also means that when we want to test this code we could inject a fake/mock/stub (depending on your understanding of these terms) and test our code.
But how can we take this further. With the use of StructureMap we can decouple this code even more. With the last code example our calling code my look something like this
public class AnotherObject
{
public void SomeMethod(IWidget widget1)
{
//..do something with widget1
}
}
public class CallingObject
{
public void AnotherMethod()
{
IWidget widget1 = new Widget();
new AnotherObject().SomeMethod(widget1);
}
}
As you can see in the above code we removed the dependency in the SomeMethod by passing in an object that conforms to IWidget. But in the CallingObject().AnotherMethod we still have the dependency. We can use StructureMap to remove this dependency too!
[PluginFamily("Default")]
public interface IAnotherObject
{
...
}
[PluginFamily("Default")]
public interface ICallingObject
{
...
}
[Pluggable("Default")]
public class AnotherObject : IAnotherObject
{
private IWidget _widget;
public AnotherObject(IWidget widget)
{
_widget = widget;
}
public void SomeMethod()
{
//..do something with _widget
}
}
[Pluggable("Default")]
public class CallingObject : ICallingObject
{
public void AnotherMethod()
{
ObjectFactory.GetInstance<IAnotherObject>().SomeMethod();
}
}
Notice that no where in the above code are we instantiating an actual implementation of AnotherObject. Because everything is wired for StructurMap we can allow StructureMap to pass in the appropriate implementations depending on when and where the code is ran. Now the code is truely flexible in that we can specify via configuration or programatically in a test which implementation we want to use. This configuration can be done on the fly or as part of a build process, etc. But it doesn't have to be hard wired anywhere.
Appologies as this doesn't answer your question regarding a case for Interfaces.
However I suggest getting the person in question to read..
Head First Design Patterns
-- Lee
I don't understand how its extra overhead.
Interfaces provide flexibility, manageable code, and reusability. Coding to an interface you don't need to worry about the concreted implementation code or logic of the certain class you are using. You just expect a result. Many class have different implementation for the same feature thing (StreamWriter,StringWriter,XmlWriter)..you do not need to worry about how they implement the writing, you just need to call it.

Is this a good factory method implementation?

I'm working on a module that requires a strictly decoupled interface. Specifically, after instantiating the root object (a datasource), the user's only supposed to interact with the object model via interfaces. I have actual factory objects (I'm calling them providers) to supply instances that implement these interfaces, but that left the clumsiness of getting the providers. To do so, I've supplied a couple methods on the datasource:
public class MyDataSource
{
private Dictionary<Type, Type> providerInterfaceMapping = new Dictionary<Type, Type>()
{
{ typeof(IFooProvider), typeof(FooProvider) },
{ typeof(IBarProvider), typeof(BarProvider) },
// And so forth
};
public TProviderInterface GetProvider<TProviderInterface>()
{
try
{
Type impl = providerInterfaceMapping[typeof(TProviderInterface)];
var inst = Activator.CreateInstance(impl);
return (TProviderInterface)inst;
}
catch(KeyNotFoundException ex)
{
throw new NotSupportedException("The requested interface could not be provided.", ex);
}
}
}
I've modified some details on the fly to simplify (e.g., this code snippet doesn't include the parameters passed to the implementation instance that's created). Is this a good general approach for implementation of a factory method in C#?
You should rather take a step back and ask whether using a factory method at all is a good idea? In my opinion, it is not.
There are more than one issue with factory methods, and your example illustrates several:
You need to have a hard reference to the implementation (FooProvider in addition to IFooProvider), which is exactly the situation you are trying to avoid in the first place. Even if the rest of your code only consumes IFooProvider, your library is still tightly coupled to FooProvider. Some other developer may come by and start using FooProvider directly if he/she isn't aware of your factory method.
You only support implementations that have default constructors, since you are using Activator.CreateInstance. This prevents you from using nested dependencies.
Instead of trying to manually control dependencies, I would recommend that you take a look at Dependency Injection (DI). Whenever your code needs an IFooProvider, supply it with Constructor Injection.
Don't reinvent your own implementation of dependency injection, use an existing library like Spring.NET or the Microsoft Unity application block.
Injecting dependencies is a common programming problem that you shouldn't have to solve yourself. There are some nice lightweight libraries out there (I mentioned a couple above) that do the job well. They support both declarative and imperative models of defining dependencies and are quite good at what they do.
Technically this is fine, however most times when I see a factory it usually returns the same type interface, for instance something like IProvider rather than IFooProvider or IBarProvider which to me doesn't make sense. If you are going to have FooProvider and BarProvider then why have different interfaces for them. I would use one interface IProvider and have FooProvider and BarProvider implement that.
Regardless of the rightness or wrongness of using the factory method (as that is not what you asked about!), your implementation looks fine to me.
Something that may work for you better than hardcoding the type mapping is putting that info in a configuration file and loading it in your app.
For what it is worth I use this pattern all the time and have abstracted some of this sort of logic into a reusable assembly. It uses reflection, generics and attributes to locate and bind the concrete types at runtime. http://www.codeproject.com/KB/architecture/RuntimeTypeLoader.aspx
This helps to address Mark's concern because implementation types are not hardcoded, and further the implementation types are determined by the installation, not in project assembly references.

Categories