I'm starting to see the value of Interfaces vs. lets say an Abstract class.
Currently I'm working on a PayPal Wrapper project. We'll also be probably doing a Google Payments, BillMeLater, and Amazon wrapper. I've been asked to identify some commonalities (methods, properties, whatever) that we could use across the board, in most any Web Service SOAP Wsdl Wrapper project for any web services we do.
So as I was coding out my PayPal wrappers, I created a new class to hold Errors received back from any PayPal response:
public class ApiError
{
#region Constructors
/// <summary>
/// Disallow default instantiation.
/// </summary>
private ApiError()
{
}
internal ApiError(ErrorType error)
{
if(error.ErrorCode != null)
{
this._errorCode = error.ErrorCode;
}
}
#endregion
#region member variables
private string _errorCode = string.Empty;
private string _erorMessage = string.Empty;
#endregion
#region Properties
public string ErrorCode
{
get { return _errorCode; }
set { _errorCode = value; }
}
public string ErrorMessage
{
get { return _errorMessage; }
set { _errorMessage = value; }
}
#endregion
}
Anyway, I said hey, these ErrorMessage and ErrorCode properties are most likely going to be in every third party API. So why not create an Interface in a new project called [MyCompany].WebServices.Common and in that interface add those 2 properties. Then any class wrapper that I create that has functionality to make API proxy calls can implement this interface and then I know any of those kinds of wrapper classes in any of our web service projects will be guaranteed to have these kind of properties in them that will be impolemented and filled with any errors that come back from an API response.
And if they do, then that's great because I can then start to create some helper methods that we can use across the board if I can somehow take in a generic response object and fill the array of errors and set the property.
Anyway, my problem is, I'm new to interfaces a litte. So the error array property from above for example is of a custom type.
Well if I create interface in a seperate physical project, I can't use that custom type because it doesn't exist..it only exists so far in my PayPal wrapper project.
So then when stubbing this interface out, how would I handle this?
namespace [MyCompany].WebServices.Common
{
interface IRequest
{
public ApiError Type { get; set; } //whoops, that's a custom type that this project does not know about (ApiError)
}
}
You should consider that the ApiErrors are going to depend on the particular web service implementation. So how would a client that is using only interfaces going to use the ApiErrors if they are implementation-specific?
It can't - because this would mean that its coupled to this particular implementation.
Instead, you need to abstract away from the specific API error codes, and define your own abstract error codes.
Every Problem in Software can be Solved with Another Layer of Indirection!!! Just add another interface called IAPIError that you implement for each pay service error type.
interface IRequest
{
public IApiError Type { get; set; }
}
You could put your shared types in a separate, shared assembly: [MyCompany].WebServices.Shared
Edit
Come to think of it, you already have that. [MyCompany].WebServices.Common should be as good a place as any for your shared types. Just move it there. Or am I misunderstanding what you want to do?
The exact error numbers and messages will be very specific for each provider. Therefore, while a common interface can be made, it will not provide enough abstraction to handle errors in a meaningful way.
I'd add another abstraction by defining the expected errors (one of which is "unknown error" as catch-all for unexpected errors) as separate class or even as set of Exceptions. Then, have each provider return or use those, which is already compatible with your application and allows you to handle common errors for all providers the same way.
Put those common types into a separate assembly, which is a pure "interface" assembly used by both the providers and the actual code using them. Therefore you'll be able to loosely couple the providers without having to add references to them in your main application (allowing you to add or modify providers without recompiling the application).
Related
over the last few days, I tried to equip my application with the service remoting IPC stack. I initially implemented the V2 version, but just noticed thanks to this post (https://github.com/Azure/service-fabric-issues/issues/735) that that does not support returning interfaces.
So, I just now made the switch to V2_1.
However, I still face this problem:
One or more errors occurred. (Type 'MooMed.Core.DataTypes.Session.SessionContext' with data contract name 'SessionContext:http://schemas.datacontract.org/2004/07/MooMed.Core.DataTypes.Session' is not expected. Add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.)'
This is the service method that is being called on the endpoint:
[CanBeNull]
public Task<ISessionContext> GetSessionContext(int accountId):
The involved classes/intefaces look like this:
public interface ISessionContext
{
Account Account { get; set; }
}
[DataContract]
public class SessionContext : ISessionContext
{
[DataMember]
public Account Account { get; set; }
}
Also, as I mentioned, I changed my remoting version from V2 to V2_1 just now, so this is added to the Service class which contains the GetSessionContext method:
[assembly: FabricTransportServiceRemotingProvider(RemotingListenerVersion = RemotingListenerVersion.V2_1, RemotingClientVersion = RemotingClientVersion.V2_1)]
So, according to the docs (https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-reliable-services-communication-remoting#use-the-remoting-v2-interface-compatible-stack) I should now be fully equipped to have everything working properly.
The only thing I see myself doing differently than the tutorial is how I declare the endpoint listeners. I'm doing this via FabricTransportServiceRemotingListener like this:
public static ServiceReplicaListener CreateTypedListener([NotNull] IService service)
{
return new ServiceReplicaListener(context => new FabricTransportServiceRemotingListener(context, service),
$"I{service.GetType().Name}");
}
However, I don't see how this could be the culprit, as the request comes in properly and I don't think declaring endpoints does necessarily interfere with how responses are serialized.
So, what am I doing wrong here?
The DataContractSerializer can't serialize an interface. (see how to mark an interface as DataContract in WCF).
However, you can write your own custom serializer to achieve this. From that article you posted at the bottom are instructions on how to do this. You can also look at my example of implementing protobuf-net here:
https://github.com/mikeruhl/Frenetik.Fabric.Remoting.Protobuf
My example should not be used in production. It's a work in progress and there are zero tests written for it at the moment.
I'm writing a DLL using C# 4.0 which will be used by several C# .NET based desktop applications (let's call them AppA and AppB). It is required that AppA will be able to use certain class' selected fields/properties/functions that won't be even available to AppB. My approach was to use internal modifier for those properties and grant access to AppA by specifying AppA's assembly name in InternalsVisibleTo attribute of the DLL. But internal modifier is also required in some properties which will be accessed in other parts of the DLL but not to be accessed by AppA. Now it appears that there are too many internals which are exposed to AppA which shouldn't be accessible by AppA.
In other words, consider the following properties:
class A
{
internal int ReallyInternal {get; set;}
internal int AppAInternal {get; set;}
}
If I use InternalsVisibleTo attribute for AppA, then both ReallyInternal and AppAInternal properties will be exposed to AppA - where as ReallyInternal shouldn't be exposed to AppA.
How to solve this? Is there any other way to implement this scenario?
Background
Before going to InternalsVisibleTo approach we thought of other ways, like having different interfaces etc. The class library I'm writing will be used by multiple applications. I wanted to have the interface same across applications.
Consider TT4 as a class in the DLL. It's properties will be populated from a physical device via serial communication.
TT4 tt4 = new TT4();
// Some code to populate tt4 object
MessageBox.Show(tt4.SerialNumber);
tt4.SerialNumber = "123";
Because tt4 object will represent a physical device, not all of its properties should be modifiable by all applications. This won't make sense and if we allow this then any application can change the serial number of the device. (Yes, SerialNumber can be written back to the device).
We've only one application (here AppA for example) which will be able to set and change the SerialNumber. Other applications shouldn't do that. It's prevented by making SerialNumber's setter as internal and granting permission to AppA by InternalsVisibleTo.
Please note that providing the library with two classes is not the solution. Say, I've implemented two classes for TT4 - TT4 (cannot write SerialNumber) and TT4Super (can write SerialNumber). When the DLL will be given to clients, they can still see TT4Super and use that.
I'm not the developer of other applications and I have no control of them.
One way to do that would be to extract all the members that should be exposed to AppA to an abstract class (or a parent class in general) and make them protected internal. To access them from AppA it would have to inherit from the abstract class. For instance
public abstract class ParentA
{
internal int ReallyInternal {get; set;}
protected internal int AppAInternal {get; set;}
}
And AppA accesses it the following way:
internal class AinAppA : ParentA
{
internal AinAppA()
{
this.AppAInternal = 1; // can access parents protected members
// this.ReallyInternal = 2; // but pure internal members are not visible
}
}
As a side note, InternalsVisibleTo is not meant to be an access modifier. It's main purpose is to make unit testing easier not to enable communication between production assemblies.
Are you mostly concerned that the designers of AppB are going to do something malicious with your DLL, or that you simply want to prevent them from doing something inadvertently? Making your members internal won't really prevent someone from doing harm via reflection if they want to.
One (admittedly not great) approach you could use is to make these members public, but prevent anyone except AppA from using them, by checking the calling assembly:
private void VerifyCaller(Assembly a)
{
if (a == Assembly.GetExecutingAssembly()) { return; }
var name = a.GetName();
if(name.Name == "AppA" && name.GetPublicKey() == appAPublicKey) { return; }
throw new InvalidOperationException("You can't access this");
}
private string _serialNumber;
public string SerialNumber
{
get { return _serialNumber; }
set
{
VerifyCaller(Assembly.GetCallingAssembly());
_serialNumber = value;
}
}
this should at least prevent anyone from easily using reflection to circumvent your defenses.
Previous Post removed; Updated:
So I have a unique issue, which is possibly fairly common though. Properties are quite possibly are most commonly used code; as it requires our data to keep a constant value storage. So I thought how could I implement this; then I thought about how easy Generics can make life. Unfortunately we can't just use a Property in a Generic without some heavy legwork. So here was my solution / problem; as I'm not sure it is the best method- That is why I was seeking review from my peers.
Keep in mind the application will be massive; this is a very simple example.
Abstract:
Presentation Layer: The interface will have a series of fields; or even data to go across the wire through a web-service to our database.
// Interface:
public interface IHolder<T>
{
void objDetail(List<T> obj);
}
So my initial thought was an interface that will allow me to Generically handle each one of my objects.
// User Interface:
public class UI : IHolder
{
void objDetail(List<object> obj)
{
// Create an Instance
List<object> l = new List<object>();
// Add UI Fields:
l.Add(Guid.NewGuid());
l.Add(txtFirst.Text);
l.Add(txtLast.Text);
// l to our obj
obj = l;
return;
}
}
Now I have an interface; which has been used by our UI to put information in. Now; this is where the root of my curiosity has been thrown into the mixture.
// Create an Object Class
public class Customer : IHolder
{
// Member Variable:
private Guid _Id;
private String _First;
private String _Last;
public Guid Id
{
get { return _Id; }
set { _Id = value; }
}
public String First
{
get { return _First; }
set { _First = value; }
}
public String Last
{
get { return _Last; }
set { _Last = value; }
}
public virtual objDetail(List<Customer> obj)
{
// Enumerate through List; and assign to Properties.
}
}
Now this is where I thought it would be cool; if I could use Polymorphism to use the same interface; but Override it to do the method differently. So the Interface utilizes a Generic; with the ability to Morph to our given Object Class.
Now our Object Classes; can move toward our Entity interface which will handle basic Crud Operation.
I know this example isn't the best for my intention; as you really don't need to use Polymorphism. But, this is the overall idea / goal...
Interface to Store Presentation Layer UI Field Value
Implement the Properties to a Desired Class
Create a Wrapper Around my Class; which can be Polymorphed.
Morphed to a Generic for Crud Operation
Am I on the right path; is this taboo? Should I not do this? My application needs to hold each instance; but I need the flexibility to adapt very quickly without breaking every single instance in the process. That was how I thought I could solve the issue. Any thoughts? Suggestions? Am I missing a concept here? Or am I over-thinking? Did I miss the boat and implement my idea completely wrong? That is where I'm lost...
After pondering on this scenario a bit, I thought what would provide that flexibility while still ensuring the code is optimized for modification and business. I'm not sure this is the right solution, but it appears to work. Not only does it work, it works nicely. It appears to be fairly robust.
When is this approach useful? Well, when you intend to decouple your User Interface from your Logic. I'll gradually build each aspect so you can see the entire structure.
public interface IObjContainer<T>
{
void container(List<T> object);
}
This particular structure will be important. As it will store all of the desired content into it.
So to start you would create a Form with a series of Fields.
Personal Information
Address Information
Payment Information
Order Information
So as you can see all of these can be separate Database Tables, but belong to a similar Entity Model you are manipulating. This is quite common.
So a Segregation Of Concern will start to show slightly, the fields will be manipulated and passed through an Interface.
public interface IPersonalInformation
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
So essentially the Interface is passing its variable, to the Interface. So you would culminate an interface to handle that entire form or individual interfaces that you wish to call so that they remain reusable.
So now you have a series of Interfaces, or a single once. But it contains all these variables to use. So you would now create a class:
public class CustomerProperties: IPersonalInformation, IOrderInformation
{
// Implement each Interface Property
}
Now you've created a container that will hold all of your values. What is nifty about this container is you can reuse the same values for another class in your application or choose different ones. But it will logically separate the User Interface.
So essentially this is acting similar to a Repository.
Now you can take these values and perform the desired logic. What becomes wonderful now, is after you've performed your logic you pass the object into our Generic List. Then you simply implement that method in another class for your goal and iterate through your list.
The honesty is it appears to work well and decouple nicely. I feel that it was a lot of work to do something similar to a normal Repository and Unit Of Work, this answers the question but weather or not it is ideal for your project I would look into Repository, Unit Of Work, Segregation Of Concern, Inversion Of Control, and Dependency Injection. They may do this same approach cleaner.
Update:
I thought about it after I wrote this up, I noticed you could actually implement those property values into the Generic List structure bypassing a series of interfaces; but that would introduce consistency issues as you'd have to be aware of what data is being passed in each time, in order. It's possible, but may not be ideal.
I was thinking about designing a proper contract for future plugins creation for an application I'm currently working on. Basically the idea is to define an interface, but I want the application to be aware of plugins that currently presented to the system and to show the user a nice list of plugins with their names and a brief descriptions which ofcourse the developer of the plugin should provide, the user of the application shouldn't be able to alter this easily so an additional config file is not an option. I don't want to use the class name of filename of the assembly for this. Also I think that it should be accessable without instantiating the plugin, but maybe through reflection, something like: assembly.GetType(type).GetProperty("Name").GetValue(null, null).ToString();. Ofcourse I could provide some logic to check for existance something like if(assembly.GetType(type).GetProperty("Name") != null), but this is not a good idea either, because if the property does not exist the end user won't have an idea of what that plugin does, not even what it's name is.
Now, it should behave like a static property, but static is not overridable so it seems that I cannot declare it as a part of an interface nor in an abstract class. Maybe I'm on wrong way, and it only looks like a static property and I can achive this functionality through another approach. So the brief question might be "How to enforce the third party developer to provide some meta information about his plugin". Please advise.
You could try with two interfaces:
IAddIn for be the main interface that all add-ins will implement.
IAddInInfo for be the interface providing the metadata of the add-in (name, publisher, description version etc.)
Each add-in should implement both of these. An IAddInInfo implementation could be like this:
public class ScannerAddInInfo : IAddInInfo
{
public string Name { get { return "Scanner"; } }
public string Description { get { return "Add-in for acquiring images from a scanner device"; } }
}
To ensure that all implementations of add-ins come with metadata, you can make IAddIn a generic interface like:
public interface IAddIn<T> where T : IAddInInfo
{
T Info { get; }
//Continue with the rest of the members you would want every add-in to have.
}
Then the scanner add-in implementation would be:
public class ScannAddIn : IAddIn<ScannerAddInInfo>
{
private ScannerAddInInfo _info = new ScannerAddInInfo();
public ScannerAddInInfo Info { get { return _info; } }
//Continue with the rest of the IAddIn implementation.
}
Then you could load the add-in assembly from a special add-in folder and create instances of the types implementing IAddInInfo and show the info from the discovered add-ins in your application. Note that no add-ins are created yet. To do so you will need to add some more reflection to find the types implementing IAddIn<ScannerAddInInfo>.
To make this simpler you could add the add-in type name to the IAddInInfo interface or something like that.
The only drawback to this approach is that you will have to load all assemblies found in your special add-in folder even if they do not include any add-ins.
To avoid this you could try Mono.Cecil. You then will have to do something like this:
AssemblyDefinition ad = AssemblyDefinition.ReadAssembly(assemblyPath);
foreach (TypeDefinition td in ad.MainModule.GetTypes())
{
if (td.BaseType != null && td.BaseType.FullName == "MyNamespace.MyAddInBase")
{
return true;
}
}
To load the assemblies you can use Assembly.LoadForm and to create instances of the add-ins and add-in infos, one of the Activator.CreateInstance overloads.
Good luck.
To add some 'meta data' to your plugins, you can use attributes. Create a custom attribute for your plugins and read out the information with reflection and show it in your application.
More info about attributes:
Creating Custom Attributes (C# and Visual Basic)
Accessing Attributes by Using Reflection
The thing you should do is basically define your interface and expect other people to implement their concrete classes and give that runtime object to you somehow (your predefined methods, configuration etc.)
But there is some mechanism called dependency injection. That allows you to define your interface and your entry points while a "system" takes care of matchmaking your entry points and implementers' concretes. There is "System.ComponentModel.Composition" namespace for this purpose.
I knew there was a framework called "Unity" doing such job. I guess composition namespace is somewhat a simplified version of unity. You can check help for "ImportAttribute" and "ExportAttribute" classes for some cue.
I'm working with a third party web service that exposes a status property on one of its classes but this property is in fact another class itself.
Whilst this is no great shakes I'm trying to make use of this web service easier for other developers in the company since the web service is abstracted away and we have our own adapter classes exposing just the properties/methods we need and I have been trying to come up with a way that will allow me to treat the status object much like a enum
What I would like to end up with is something like object.status = StatusAdapter.<value>
Before anybody says 'simply use an enum' the reason I am not simply using an enum is that the status data that the web service object represents can be added to by a user at any time which means that I'd have to change the class library and re-deploy to all applications that use it.
Any ideas?
Edit
To clarify I want the end developers to be able to do the following, along the lines of an enum when StatusAdapter is not an enum but populated dynamically at run time.
If(foo.Status == StatusAdapter.NotStarted){...}
Use Interface. That should do the job.
Take for example, do this
public interface IStatus
{
}
public class SuccessStatus: IStatus
{
}
public class FailStatus: IStatus
{
}
in your class, you can do this:
public class CheckWebService
{
public IStatus Status
{get;set;}
}
So anyone using your class can do this easily:
var checking = new CheckWebService();
checking.Status=new SuccessStatus();
Or define their own status which is inherited from IStatus and use it.
In this way you don't have to redeploy your code and yet still able to let users define their own statuses.
The only way would be to have a number of properties on StatusAdapter which are of type StatusAdapter and return different values of StatusAdapter