I'm attempting to put a web service wrapper around several third-party web services. For the sake of this question, we'll work with two of them:
OrderService
AddressService
Both of these services have the same object defined in different namespaces:
OrderService.AuthenticationParameters
AddressService.AuthenticationParameters
I was hoping to be able to create a single base class that would be able to detect/switch between namespaces. For example:
public abstract class BaseLogic
{
internal BaseLogic()
{
/* Initialize authParams */
//Switch out / detect namespace here
this.authParams = new OrderService.AuthenticationParameters();
this.authParams.accountName = "[MyAccountName]";
this.authParams.userName = "[MyUserName]";
this.authParams.password = "[MyPassword]";
}
}
I've seen several similar questions. Either they don't apply to my situation, or I'm incapable of understanding them.
Question: Is what I'm trying to achieve possible? If it's possible, am I over complicating things?
Additional Info: Eventally, there will be more than two services that share this common object. The vendor provides a separate service URL for each branch of functionality they provide.
There are quite a few solutions to this.
Have your service proxy classes implement your own interface to expose the methods, and then simply use reflection to build a type.
Wrap both services in another class that exposes the methods and has a reference to both services, then simply provide a switching argument to determine which to use.
Abstract the use of a service via your own interface and have classes coded against each service explicitly (see below).
Or if you want to play with dynamic and duck typing, this seemed to work:
namespace ConsoleApplication42
{
class Program
{
static void Main(string[] args)
{
Type t1 = Type.GetType("ProviderOne.AuthService");
dynamic service = Activator.CreateInstance(t1);
Console.WriteLine(service.GetUsername());
Type t2 = Type.GetType("ProviderTwo.AuthService");
service = Activator.CreateInstance(t2);
Console.WriteLine(service.GetUsername());
Console.Read();
}
}
}
namespace ProviderOne
{
public class AuthService
{
public string GetUsername()
{
return "Adam";
}
}
}
namespace ProviderTwo
{
public class AuthService
{
public string GetUsername()
{
return "Houldsworth";
}
}
}
Bear in mind they all hinge on both services having the same signature.
As for the other services in future, it really depends. I've never really encountered a need to dynamically switch from one service to another to get slightly different behaviour in achieving the same thing.
Perhaps this should be driven from your app's side? Instead of a service being chosen to suit, simply implement two versions of the class that has this changing behaviour - put a common interface on it, and decide which of your classes to use at runtime. The class itself will then be coded directly against one of the services.
interface IGetUsername
{
string GetUsername();
}
class UsernameViaProviderOne : IGetUsername
{
public string GetUsername()
{
return new ProviderOne.AuthService().GetUsername();
}
}
class UsernameViaProviderTwo : IGetUsername
{
public string GetUsername()
{
return new ProviderTwo.AuthService().GetUsername();
}
}
Then the decision is firmly in your client code and removes the need for reflection/dynamic typing:
IGetUsername usernameProvider = null;
if (UseProviderOne)
usernameProvider = new UsernameViaProviderOne();
...
To labour the point, you could always get very SOA and create yet another service that your app talks to that aggregates the other two services. Then at least your client code doesn't see the huge number of different services and talks to just one.
Hm, the only thing i can think of is to use reflection to create the object. The problem is that you have to use reflection again to set the properties, call methods etc., because i guess you don't have a shared interface. While its a lot of work and it might decrease the performance, it does the trick.
Have a look at the Activator with CreateInstance you can pass a full qualified class name and create your instance.
Then, using the Type of this new created object you can search for the properties you want to modify.
You may use #if.
#if true
using MyService.X;
using x=MyService.A;
#endif
#if false
using MyService2.X;
using x=MyService.B;
#endif
But you can not change in on run time as it works on compile time.
Note: Not a good programming practice. But this exists.
Related
I am working on a C# project that sits on top of a 3rd party CMS. The team is leveraging Dependency Injection to promote loose coupling between classes.
I have the need to "extend" the apis of the CMS with common functions that are used in several pages.
What makes it interesting is these common functions have multiple dependencies.
In this case, is it more appropriate to extend this functionality using static extension methods or by creating new interfaces?
Context
Let's say the 3rd Party has two interfaces IContentLoader and IPageSecurity that work with Page objects:
namespace 3rdParty.Api
{
public class Page{}
public interface IContentLoader{
T LoadItem<T>(Guid id) where T : Page;
}
public interface IPageSecurity
{
bool CurrentUserCanReadPage(Page p);
}
}
And I want to write a common method like:
public IEnumerable<T> LoadAllChildPagesTheUserCanRead(Guid id) where T:Page
{
//load page, recursively collect children, then
//filter on permissions
}
(I admit this example is a bit trite)
Extension Methods
I could create a static extension method using Property Injection:
public static class IContentLoaderExtensions
{
public static Injected<IPageSecurity> PageSecurity {get;set;}
public static IEnumerable<T> LoadAllChildItems(
this IContentLoader contentLoader, Guid id){}
}
This method is then very discoverable, we use IContentLoader often so it's easier for a team member to find it. However, I have read that Property Injection is generally less beneficial than Constructor Injection and should be avoided if possible.
Wrapper
On the other hand, I could create a Wrapper:
public class AdvancedContentLoader
{
public AdvancedContentLoader(IContentLoader c, IPageSecurity p){
//save to backing fields
}
IEnumerable<T> LoadAllChildItems(Guid id){}
}
This approach allows for Constructor Injection, which avoids the potential hazards of Property Injection, but makes the method less discoverable. The consumer would need to know to depend on AdvancedContentLoader instead of using the IContentLoader they are use to.
Summary
In this case where a method has multiple dependencies, is it better to promote discoverability by using an extension method and take whatever brittleness may come from using Property Injection? Or is Construction Injection so favorable that I should create a wrapper class at the cost of making the method harder to find?
I would lean more towards the wrapper class but I would create another interface for it. I would name it similar so developers can find it.
public interface IContentLoaderWithPageSecurity : IContentLoader
{
IEnumerable<T> LoadAllChildItems<T>(IContentLoader contentLoader, Guid id) { }
}
New interface but same starting name so intellisense can help developers. Also this interface has to implement the 3rd party interface.
I would change your AdvancedContentLoader class to implement this interface and chain all calls to IContextLoader to 3rd party implementation and handle just the specific methods it needs to handle.
public class AdvancedContentLoader : IContentLoaderWithPageSecurity
{
private readonly IContentLoader _internalContentLoader;
private IPageSecurity _pageSecurity;
public AdvancedContentLoader(IContentLoader contentLoader, IPageSecurity pageSecurity)
{
_internalContentLoader = contentLoader;
_pageSecurity = pageSecurity;
}
// Chain calls on the interface to internal content loader
public T LoadItem<T>(Guid id) where T : Page
{
return _internalContentLoader.LoadItem<T>(id);
}
public IEnumerable<T> LoadAllChildItems<T>(IContentLoader contentLoader, Guid id)
{
// do whatever you need to do here
yield break;
}
}
The benefits of this is if you are using DI Container you can just register IContentLoaderWithPageSecurity interface to the class and you are still coding to an interface.
The naming convention helps the developers find it with intellisense, if the namespace of the class is in the using directive.
The new interface implements the old one so existing code base that needs IContentLoader you can still pass down IContentLoaderWithPageSecurity into those methods.
I would only lean towards extension methods if I didn't require a new dependency and could just just what is already there - otherwise you have to get "smart" and do property injection or something like the ConditionalWeakTable to hold extra state for the class.
I agree with Wiktor Zychla that this starts to become peoples subjective opinions.
I suggest a decorated content loader. This approach follows SRP principle, where you don't mix responsiblities - I still have a content loader and when I want to implemenet loading multiple elements, I delegate this to another class.
public class DecoratedContentLoader : IContentLoader
{
IContentLoader c;
IPageSecurity p;
public DecoratedContentLoader(IContentLoader c, IPageSecurity p)
{
this.c = c;
this.p = p;
}
public T LoadItem<T>(Guid id) where T : Page
{
var page = c.LoadItem<T>( id );
if ( p.CanUserReadPage( p ) )
return p;
// throw or return null
}
}
As you can see, this uses the security provider but still implements a single item provider interface.
Thus, another class responsible for loading multiple items can just take IContentProvider as an argument and use either the bare one or the decorated one without distinguishing between the two.
public class AdvancedContentLoader
{
// no need for additionak parameters, works
// with any loader, including the decorated one
public AdvancedContentLoader( IContentLoader c )
{
//save to backing fields
}
IEnumerable<T> LoadAllChildItems(Guid id){}
}
So, my initial reaction to this is that there might be a bit of over-thinking going on here. If I understand your question correctly, you are trying to figure out the easiest way to extend a third party API. In this case, the API has an interface that you like, IContentLoader, and your goal is to add another method to this interface which enables it:
in addition to loading a given page (defined by Guid),
to recursively load all child pages as well,
so long as the user has permission (which is in the responsibility of IPageSecurity).
According to Microsoft,
Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.
Which, if I understand, is exactly what you are trying to do here. I will admit that the structure and function for IPageSecurity does not make much sense to me, and that could be the reason behind the confusion. Bottom line, is there any reason why you would choose not to go this route? Perhaps your purpose is complicated by your example.
Say I have an Interface like this in a project called "Interface":
public interface TestInterface
{
string Operation();
}
and class which implements it. This class is located in another project "Class":
public class TestClass : TestInterface
{
public TestClass() { }
public string Operation()
{
return "This is an Operation";
}
}
My client does something like this (which is again in a different project "Client"):
class Program
{
static void Main(string[] args)
{
TestInterface i = new TestClass();
i.Operation();
}
}
My question is related to this line:
TestInterface i = new TestClass();
By adding this line, I'm actually forced to add a references to both "Interface" as well as "Class" projects from my "Client" project. So why all this fuss? Can't I directly refer to the "Class" without keeping the "Interface" in between? Is there any way to access the methods via Interface only (without making a reference to the implementation Class)? Am I missing something here?
Is there any way to access the methods via Interface only
Yes, there is. You can dynamically load an assembly with TestClass without referencing it, create its instance via Activator.CreateInstance and cast it to interface type:
var assembly = Assembly.Load(...);
var typeFromAssembly = assembly.GetTypes()...;
var myInterfaceVar = (TestInterface)Activator.CreateInstance(typeFromAssembly);
...or... you may use one of existing DI-frameworks (e.g. MEF) and do the same thing more right way:
[Import]
private TestInterface myInterfaceField;
or:
var myInterfaceVar = compositionContainer.GetExportedValue<TestInterface>();
Depending of the way you prefer, you may ask more concrete question.
In that particular sample, there is no advantage.
But imagine a method:
public void Foo(ITestInterface handler)
{
handler.Operation();
}
Now, Foo operates only on the interface and it doesn't care what concrete class implements this interface. You could now call Foo with an instance of TestClass or with TestClass2, which could be defined in a different assembly.
you can achieve the behavior you have described via using IOC.
Unity is a dependency injection container which allows to create instances without manually creating instances.
For instance, if you were to register your class and interface to unity, you would directly use the interface;
TestInterface i = Container.Resolve<TestInterface>();
To make your code completely independent from implementation of TestInterface use Dependency Inversion. This could be achieved by some Dependency Injection framework.
E.g. with Unity you can configure implementation via xml
<register type="TestInterface"
mapTo="Foo.Bar.TestClass, Foo.Bar" />
And your code will depend only on Unity (no references to implementation):
TestInterface i = Container.Resolve<TestInterface>();
You have interface so that your app can have plug in's..
So basically you share your Interface dll to anyone who wants to make a plugin app for your app and then you can cast that new plugin class to the interface and invoke methods on it..
If you dont cast the class to the interface,how on earth are you going to make the plugin class work for your app..
I am having the following problem. I have a main project, and some extra projects that have similar functionality.
For example: I have an MVC website, then a class library project "A" with a "SettingsHelper". This just defines static wrappers for configuration settings so they can be used as propertys.
Then I have another class library project "B", which also contains a "SettingsHelper class".
How can I merge these SettingsHelpers in my main project, so I can use: SettingsHelper.Property from both modular extra projects.
I would like to be able to plug extra class libraries into one project.
Sounds pretty much like Dependency Injection. Normally you would expose SettingsHelper as an interface (your contract), and program against that. Then a DI container, such as Ninject, StructureMap, or Windsor would plug an implementation of that interface into the relevant parts of your code based on configuration.
This would allow you to code against a known contract and provide different libraries depending on the circumstances, the DI framework could then use that library to get the concrete implementation of the interface.
Would you need both instances at the same time?
Note that you cannot utilise the partial keyword across different assemblies, only within an assembly.
Update: based on your comment it sounds like you want to do something like Composition. Have a class that takes both classes from either library and combines them into one class that can be used by your application. Whether you then configure it to do something special or load the types when the libraries are present, it can all be encapsulated in this new class.
Update 2: alternatively, look into MEF:
http://msdn.microsoft.com/en-us/library/dd460648.aspx
That won't work. Partial classes cannot be divided over assemblies -- they don't exist in the CLR, only in the editor and the compiler. So they are compiled together into a single CLR class.
What you can do, is inherit one from the other. However, helpers tend to be static classes, so that won't work either.
The other alternative is not to write helper classes, but extension methods. You can extend classes in one assembly with methods defined in another assembly (or multiple other assemblies). See also http://msdn.microsoft.com/en-us/library/bb383977.aspx.
I would say that move both Helper classes in 3rd project and add reference of that project to both of your projects. So this new library will become shared datastructures and functionalities library.
Regards.
The specific pattern you are after is called a Facade Pattern. Unfortunately you are not going to get any help from the compiler getting this right. Essentially:
Create a new CombinedSettingsHelper class in your local assembly.
If the two SettingsHelper types are in the same namespace you will need to set up aliases for them (check the reference properties in the solution explorer, and MSDN documentation for this).
Implement the object so that it can access both SettingsHelper objects.
To clean up your facade you might try having a abstract method along the lines of abstract object GetSettingValue(string name);. Your facade could then inherit from the same base class and call these on its contained children. For example:
public abstract class SettingsHelperBase { public object GetSettingValue(string settingName); }
// Assembly1
public class SettingsHelper : SettingsHelperBase { }
// Assembly2
public class SettingsHelper : SettingsHelperBase { }
public class SettingsHelper : SettingsHelperBase
{
private List<SettingsHelperBase> _backends = new List<SettingsHelperBase>();
public readonly PropertiesImpl Properties;
public class PropertiesImpl
{
private SettingsHelper _settingsHelper;
public string Name
{
get
{
return (string)_settingsHelper.GetSettingValue("Name");
}
}
internal PropertiesImpl(SettingsHelper helper)
{
_settingsHelper = helper;
}
}
public SettingsHelper()
{
_backends.Add(asm1::MyNs.SettingsHelper);
_backends.Add(asm2::MyNs.SettingsHelper);
Properties = new PropertiesImpl(this);
}
protected override object GetSettingValue(string settingName)
{
foreach (var item in _backends)
{
var val = item.GetSettingValue(settingName);
if (val != null)
return val;
}
return null;
}
}
There is a way; Visual Studio allows the same code file to be included in more than one project.
When you do “Add”/”Existing Item” to can select a file that is in the different folder.
This is what some of the silver light support does so as to allow a “common class” that has some method that are only on the server and one methods that are only on the client.
(As to the question of “good design” you will have to decide that yourself, a lot of people don’t like having the same class compiled in different ways in different projects. Think if the mess you could get in with #if XXX, when XXX is only defined in one of the projects)
Consider the following:
public Something(IInterface concreteObjectOne, IInterface concreteObjectTwo)
{
this.concreteObjectOne = concreteObjectOne;
this.concreteObjectTwo = concreteObjectTwo;
}
How do I set set this type of binding up with Ninject? I'd try Googling the term, but as I'm not sure what this is called I can't, nor can I find anything on the Wiki about this.
Edit:
I believe this is called Convention Based Binding, as described here. However this documentation is for version 1.0 and 2.0 does not have the Only method. I'd like this to be achieved without attributes - using the convention of names or something similiar.
In addition to the use of "Only" method, the article suggests another solution by specifying different attributes for the injected objects.
Example:
public class ObjectOneAttribute : Attribute
{
}
public class ObjectTwoAttribute : Attribute
{
}
Then
public Something([ObjectOneAttribute] IInterface concreteObjectOne, [ObjectTwoAttribute] IInterface concreteObjectTwo)
{
this.concreteObjectOne = concreteObjectOne;
this.concreteObjectTwo = concreteObjectTwo;
}
And when you want to bind the interface to the correct concrete object, use the "WhereTargetHas" method:
Bind<IInterface>().To<YourConcreteTypeOne>().WhereTargetHas<ObjectOneAttribute>();
Bind<IInterface>().To<YourConcreteTypeTwo>().WhereTargetHas<ObjectTwoAttribute>();
Update: Solution without using attributes:
Use the method "When":
Bind<IInterface>().To<YourConcreteTypeOne>().When(r => r.Target.Name == "concreteObjectOne");
Bind<IInterface>().To<YourConcreteTypeTwo>().When(r => r.Target.Name == "concreteObjectTwo")
;
If I may be allowed to offer some general, instead of Ninject-specific, guidance on this, I would suggest that you reconsider your design slightly. The current constructor is vague because it offers no guidance about which implementation of IInterface that goes where - I realize that this is just a mock-up of your real API, and while the real API may offer more help to the human developer in the form of aptly named parameters, a machine like a DI Container cannot infer correct usage.
Many DI Containers offer some way to address such vagueness, for example by providing attributes you can use to associate names (metadata) with each dependency. AFAIR, Ninject has Inject attributes...
However, consider a couple of alternatives:
The first alternative is to encapsulate the two similar interface instances in an Parameter Object, like this:
public interface IParameterObject
{
IInterface ObjectOne { get; }
IInterface ObjectTwo { get; }
}
You can now change the constructor to take an instance of IParameterObject instead of the two interface instances themselves.
public Something(IParameterObject po)
{
this.concreteObjectOne = po.ObjectOne;
this.concreteObjectTwo = po.ObjectTwo;
}
This means that you can push configuration of IParameterObject to the Composition Root.
Another alternative to ponder is whether it makes sense to consider the case with two instances as just a special case of a more general design that takes any number of instances. This may not always be the case, but if it is, you can change the constructor to this:
public Something(IEnumerable<IInterface> objects)
I would personally prefer any of the above suggestions over anything that uses specific Ninject features, because it forces me to make the API more explicit in general, and thus more readable and maintainable.
In Visual Studio 2008 using C#, what is the best way to share code across multiple classes and source files?
Inheritance is not the solution as the classes already have a meaningful hierarchy.
Is there some neat feature that's like a C include file that let's you insert code anywhere you want in another class?
EDIT:
ok, i guess we need a concrete example...
There are several hundred classes in the domain with a well thought out class heirarchy. Now, many of these classes need to print. There is a utility printer class that handles the printing. Let's say there are 3 different print methods that are dependent on the class that is being printed. The code that calls the print method (6 lines) is what I'm trying to avoid copying and pasting across all the different client class pages.
It'd be nice if people wouldn't assume they knew more about the domain that the op - especially when they specifically mention techniques that don't fit...
If you have functionality that you use frequently in classes that represent very different things, in my experience that should fall into just a few categories:
Utilities (e.g. string formatting, parsing, ...)
Cross-cutting concerns (logging, security enforcement, ...)
For utility-type functionality you should consider creating separate classes, and referencing the utility classes where needed in the business class.
public class Validator
{
public bool IsValidName(string name);
}
class Patient
{
private Validator validator = new Validator();
public string FirstName
{
set
{
if (validator.IsValidName(value)) ... else ...
}
}
}
For cross-cutting concerns such as logging or security, I suggest you investigate Aspect-Oriented Programming.
Regarding the PrintA vs. PrintB example discussed in other comments, it sounds like an excellent case for the Factory Pattern. You define an interface e.g. IPrint, classes PrintA and PrintB that both implement IPrint, and assign an instance of IPrint based on what the particular page needs.
// Simplified example to explain:
public interface IPrint
{
public void Print(string);
}
public class PrintA : IPrint
{
public void Print(string input)
{ ... format as desired for A ... }
}
public class PrintB : IPrint
{
public void Print(string input)
{ ... format as desired for B ... }
}
class MyPage
{
IPrint printer;
public class MyPage(bool usePrintA)
{
if (usePrintA) printer = new PrintA(); else printer = new PrintB();
}
public PrintThePage()
{
printer.Print(thePageText);
}
}
You can't just load in code that you'd like to have added into a class in C# via a preprocessor directive like you would in C.
You could, however, define an interface and declare extension methods for that interface. The interface could then be implemented by your classes, and you can call the extension methods on those classes. E.g.
public interface IShareFunctionality { }
public static class Extensions
{
public static bool DoSomething(this IShareFunctionality input)
{
return input == null;
}
}
public class MyClass : Object, IShareFunctionality
{
public void SomeMethod()
{
if(this.DoSomething())
throw new Exception("Impossible!");
}
}
This would allow you to reuse functionality, but you cannot access the private members of the class like you would be able to if you could, say, hash include a file.
We might need some more concrete examples of what you want to do though?
A C# utility class will work. It acts like a central registry for common code (or like the VB.NET Module construct) - it should contain code that's not specific to any class otherwise it should have been attached to the relevant class.
You don't want to start copying source code around if you don't have to because that would lead to code update problems considering the duplication.
As long as the source doesn't need to retain state, then use a static class with static method.
static public class MySharedMembers {
static public string ConvertToInvariantCase(string str) {
//...logic
}
// .... other members
}
If the classes are in the same namespace, there's no need for an include analog. Simply call the members of the class defined in the other function.
If they're not in the same namespace, add the namespace of the classes you want to use in the usings directives and it should work the same as above.
I'm confused by the question: it seems you need to work on your basic OO understanding.
Checkout extension methods: http://msdn.microsoft.com/en-us/library/bb383977.aspx
I don't know of a way to include portions of files but one thing we do frequently is to add an existing file and "link" it from its current location. For example, we have an assemblyInfo.cs file that every project refers to from a solution directory. We change it once and all the projects have the same info because they're referring to the same file.
Otherwise, suggestions about refactoring "common" routines in a common.dll are the best thing I've come up with in .Net.
I am not sure exactly what you mean by a "meaningful" structure already, but this sounds like a place where you could use base class implementation. Though not as "verbose" as C++ multiple inheritance, you might get some benefit out of using chained base class implementation to reuse common functions.
You can preserve class hierarchy, at least visually and override behavior as needed.
Pull out the repetitive code into services. The repetitive code is a clue that there might be some room for refactoring.
For example, create a "PrintingService" which contains the logic needed to print. You can then have the classes that need to print have a dependency on this service (either via the constructor or a parameter in a method which requires the service).
Another tip i have along these lines is to create interfaces for base functionality and then use the interfaces to code against. For example, i had bunch of report classes which the user could either fax, email, or print. Instead of creating methods for each, i created a service for each, had them implement an interface that had a single method of Output(). I could then pass each service to the same method depending on what kind of output the user wanted. When the customer wanted to use eFax instead of faxing through the modem, it was just a matter of writing a new service that implemented this same interface.
To be honest I can't think of anything like includes in Visual C#, nor why you would want that feature. That said, partial classes can do something like it sounds what you want, but using them maybe clashes against your "classes already have a meaningful hierarchy" requirement.
You have many options, TT, extension method, delegate, and lambda