Looking for pattern to combine partial classes from different assembly's - c#

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)

Related

Inheritance from two swappable class libraries

C# solution structure
Project ApiReduced: A class library containing a file Reference.cs generated by a tool. It contains dozens of partial classes, most of which inherit from another .NET class, e.g. the class ODataService inherits from DataServiceContext. The classes are all in the same namespace Som.
Project ApiFull: Class library same as ApiReduced, but contains more partial classes, classes have further properties, etc. Think of it as a superset of ApiReduced. Again, under the same namespace Som.
Project ApiExtensions: Contains Extensions.cs, which should either (not yet decided if inheritance or extension methods make most sense)
inherit from either of the ODataService classes or
provide extension methods for the classes in either project ApiReduced or ApiFull
Project MyProject: Contains code that references either project ApiReduced or ApiFull. Furthermore, it references ApiExtensions.
Desired effect
What I want to accomplish with the above is to be able to decide in MyProject what API to use (full or reduced), depending on whether I add a reference to ApiReduced or ApiFull. In reality I have several projects, some should use the full API, some the reduced API, but I want to be able to use the same extensions in either case to avoid code duplication.
What I've tried
When in ApiExtensions I reference both ApiReduced and ApiFull, I naturally get a lot of errors that the types defined in Reference.cs exists in both libraries. On the other hand, how can I implement Extensions.cs without referencing at least one of ApiReduced or ApiFull? And if I make a choice, that seems rather arbitrary.
TL;DR
How can I swap between using two nearly identical class libraries (in the sense they define partial classes with the same names in same namespace) for my extension methods/derived class?
Short answer: Interfaces and dependency injection!
Any behaviour you want to add an extension to should be based on an interface, and then you implement that interface in both your Full & Reduced api classes. Your extensions assembly should only reference the interfaces assembly and add extensions as appropriate. At this point your assemblies look like
ApiFull (references ApiInterfaces)
ApiReduced (references ApiInterfaces)
ApiExtensions (references ApiInterfaces)
ApiInterfaces
MyProject (references ApiExtensions, ApiInterfaces and either ApiFull or ApiReduced)
Then in your project you again only code against interfaces, and in that way you can use the extensions as necessary. In this project, you use Dependency Injection to inject the correct concrete class (from either ApiFull or ApiReduced)
No answer is complete without a code sample. So, adding extensions to interfaces:
using System;
public class Program
{
public static void Main()
{
var foo = new Foo();
Console.WriteLine(foo.SayHello());
}
}
public static class INamedExtensions
{
public static string SayHello(this INamed named)
{
return $"Hello from {named.Name}";
}
}
public class Foo : INamed
{
public string Name {get => "Foo";}
}
public interface INamed
{
string Name{get;}
}
I suggest you split your Extensions into ApiReducedExtensions and ApiFullExtensions.
That way, when you want to use the Reduced API in a project you include ApiReduced and ApiReducedExtensions
And when you want to use only the FullApi, you only include ApiFull and ApiFullExtensions
Edit
To avoid duplicated code between the two you can add another class ApiSharedExtensions which contains the code both have in common. Same for the Api

Implementing 2 C++/CLI interfaces in separate projects causing <type> exists in both DLLs error in C# app

I'm working on a large API project that needs to release 2 DLLs with many interfaces written in C++/CLI (one DLL contains interfaces for public use and the other extends some of the public interfaces for internal company use only).
All implementation classes for all interfaces are in a separate project and are all contained in a separate DLL as well.
Most internal interfaces usually just extend the public version by one by 1 or 2 methods, I opted to reuse the same implementation classes for code reuse.
Here's an example:
//Company.PublicInterfaces.dll
namespace Company
{
namespace PublicInterfaces
{
//contains public properties, methods, etc that any developer can use
public interface class ICompanyProduct
{
void GetProductInfo();
//...etc
}
public interface class IOtherStuff
{
void GetOtherStuff();
}
//...plus many more interface definitions
}
}
//Company.InternalInterfaces.dll
namespace Company
{
namespace InternalInterfaces
{
//extends the public interface to include secret methods that only company developers can use
public interface class ICompanyProductInternal : ICompanyProduct
{
void GetSecretInfo();
//...etc
}
//...plus many more interface definitions
}
}
//Company.InterfaceImplementations.dll
#include "Company.InternalInterfaces.h"
namespace Company
{
namespace InterfaceImplementations
{
public ref class CompanyProductImplementer : ICompanyProduct, ICompanyProductInternal
{
//implements both interfaces
}
public ref class OtherStuffImplementer : IOtherStuff
{
//implement other stuff
}
//...plus many more interface implementations
}
}
//C# Test App
using Company.InternalInterfaces
using Company.PublicInterfaces
using Company.InterfaceImplementations
namespace TestApp
{
class TestAppProgram
{
static void Main()
{
//write code that uses both interfaces for reusability or for whatever reason....
ICompanyProductInternal internalProduct = new CompanyProductImplementer();
IOtherStuff otherStuff = new OtherStuffImplementer();
}
}
}
The Company.InternalInterfaces project references the Company.PublicInterfaces project.
Since we can't ship Company.InternalInterfaces.dll, the Company.InterfacesImplementation project can only reference Company.PublicInterfaces or we risk exposing the internal interfaces.
But since class CompanyProductImplementer also implements ICompanyProductInternal, I had to include "Company.InternaInterfaces.h".
When building the C# test app, Visual Studio 2013 complains of
Error: The type 'Company.InternalInterfacs.ICompanyProduct' exists in both 'Company.InterfacesImplementation.dll' and 'Company.InternalInterfaces.dll'
The only way it works is if the implementation project also references the internal interface project, but that's not possible because I'll have to ship the internal interface library as well.
How can I solve this? Obviously this is a typical scenario with regards to many companies wanting to reuse their code for public and internal use in large projects.
As I see Company.InternalInterfaces.dll and Company.PublicInterfaces.dll are only interface dlls for the same Company.InterfaceImplementations.dll where all logic implemented. Such configuration typically used when you don't need to hide functionality, but because of usability reasons. In this configuration anyone could access Company.InterfaceImplementations.dll code logic via decompilation and execute any code via reflection.
To hide internal logic you could extract Company.Base.dll with common services used by everyone and split other code from Company.InterfaceImplementations.dll into internal Company.Internal.dll and public Company.Public.dll. In such case you need to distribute Company.Base.dll and Company.Internal.dll or Company.Base.dll and Company.Public.dll.
The other option is to create two build configurations PublicAPI and InternalAPI for Company.InterfaceImplementations.dll. In different configurations, different #define directive should be used. In this case code logic could be included or excluded based on this #define. It will give you ability to exclude internal logic from public dlls.
Error: The type 'Company.InternalInterfacs.ICompanyProduct' exists in both 'Company.InterfacesImplementation.dll' and 'Company.InternalInterfaces.dll'
Any way you should split your code properly to prevent duplicate definitions of the same interfaces in several dlls. Place it in only one dll, e.g. Company.Base.dll.
To properly consumes C++-CLI types defined in other assembles you should use using. E.g:
using "Company.InternalInterfaces.dll"
instead of
#include "Company.InternalInterfaces.h"
in your Company.InterfaceImplementations.dll assembly. Useful C++-CLI article "How to: Define and Consume Classes and Structs".

C# share code between classes

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

Class implementations in interface dll?

my problem: Inside an application, all interfaces are declared inside an own dll(project "interfaces", for example).
Inside project interfaces, there are many class implementations, too.
Now I need one of this implemented classes inside another project and get a ring dependency because this project is also a reference in project interfaces.
So, what is the best way to get around this ring dependency? Could it be possible that this is a big mistake in the design of the application?
Schematic representation:
IBigInterface.cs (everything in one file):
interface ISomeInterfaceA
{
void SomeFunctionA(ClassB x); // ClassB from newProject.cs
void SomeFunctionB();
}
//
// etc.
//
class ClassA
{
//
// Code
//
}
newProject.cs (everything in one file):
class ClassB
{
//
// used in interfaces.dll
//
}
class ClassC
{
void SomeFunction(ClassA a) // ClassA from IBigInterface.cs
{
//
// do something
//
}
}
First thing that comes into my mind would be sth. like:
IBigInterface.cs:
interface ISomeInterfaceA
{
void SomeFunctionA(IInterfaceB x); // use interface instead of a class
void SomeFunctionB();
}
interface IInterfaceB
{
//
// declarations
//
}
class ClassA
{
//
// implementation
//
}
newProject.cs:
class ClassB : IInterfaceB // implementation of IInterfaceB
{
}
class ClassC
{
void SomeFunction(ClassA a)
{
//
// implementation
//
}
}
so that project newProject wouldn't be a reference in project interfaces anymore (although this means changes in the whole application).
P.S.: I inherited this application so the idea of implementing classes in an interface-project was not my idea :).
In General, I would create one file per class (so don't point to this :).
First, there's nothing wrong with combining concrete classes and the interfaces they implement into a single assembly (though it would be a bit strange to call the project "interfaces").
Having said that, circular references are usually a sign that you've over-modularized your code: the parts causing the circular reference belong together and they should be merged into a single assembly.
Other times, a circular reference is just a sign that a class is in the wrong layer; the class needs to be moved into another assembly altogether (usually out of a lower-level infrastructure assembly and into a higher-level assembly). For example, ClassC might really belong in another project that references the "interfaces" assembly.
That's exactly the reason why Java requires public definitions to be in their own files (but I think you get the concept here :)).
It's usually not good to mix pure interface and implementation (though there are cases where it could be useful), and it's definitely a troublemaker if you export those into DLLs.
A cyclic dependency means your projects are too coupled to be distinct. This is usually a symptom of bad design (big ball of mud-like). You should either work on removing that coupling or merge both projects together.
If you have a specific project that, as you say, contains all your interfaces, why not introduce another project that contains "helper classes" such as ClassA? Then your interface DLL and the projects depending on the interface DLL could use the classes.
I would try to factor out the classes and interfaces that are common to several projects into a "Common" assembly (or similar), which has no dependencies to the assemblies that reference it.
For example, a business entity such as Product does not have to know anything about how it is persisted to a database or fetched via a web service, but the service components that do things with Product, for example IProductsRepository, needs to know what a Product is. Thus the assembly (or namespace) where IProductsRepository is defined holds a reference to the assembly (or namespace) where Product lives, but not the other way around.

Ninject Binding

How do bind my interface to a concrete class in a different assembly?
I have the following projects in my solution:
Foo.Data
Foo.Domain
In Structure Map I add my two assembly names to the StructureMap.config file and a then using the PluginFamily and Pluggable attributes map my interfaces to my concrete class'.
How can accomplish the same thing with Ninject?
I'll make a couple of assumptions here.
You have an interface named IBar in your Foo.Domain project and you have a concrete class called BarClass in your Foo.Data project.
You in fact reference Foo.Domain project in your Foo.Data project because BarClass implements IBar.
The simplest thing to do with Ninject is to create a new class in Foo.Data that derives from Ninject's StandardModule:
internal class BarModule : StandardModule {
public override void Load() {
Bind<IBar>()
.To<BarClass>();
}
}
This class then establishes the binding for requests of IBar to the concrete class of BarClass. This is your XML equivalent.
The next step is to create the Ninject kernel (aka a "container") and provide this module (i.e. this configuration) to it. Where you do this depends greatly on what kind of an application you are creating. In very general terms, you will typically configure the kernel at the logical entry point or "start-up" section of your code. If it were a console or Windows desktop application, this would likely be one of the first things that the main() function does.
The code would like this:
var modules = new IModule[] {
new BarModule()
};
var kernel = new StandardKernel(modules);
At this point, when you do something like this:
var barObj = kernel.Get<IBar>()
The variable barObj references an instance of BarClass.
All said, I could very well not have a full understanding of all the nuances of your application -- e.g. assemblies are loaded dynamically, etc. Hope this is of some help anyway.

Categories

Resources