[C#] Meerdere DLLs implementeren identieke interface

Pagina: 1
Acties:

Onderwerpen


  • hell4you
  • Registratie: Mei 2006
  • Laatst online: 16:36
Ik ben op zoek naar een manier om in C# ergens een generieke interface te definiëren, zodat die in meerdere assemblies bekend is. Het doel is natuurlijk om deze objecten later te kunnen hergebruiken in meerdere applicaties met mogelijk een ander doel. Zie het volgende voorbeeld:

Afbeeldingslocatie: http://i55.tinypic.com/2iv1ul0.png

Het doel is dus om de IO interface generiek te maken voor alle DLLs. Het maakt niet uit wat de implementatie verder is. Zo kan ik in de applicatie een lijst bijhouden van alle IO's en daar willekeurige acties op uitvoeren.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
namespace IOControl
{
    public interface IIO
    {
        bool Get();
        void Set(bool value);
    }
    
    public class App
    {
        private List<IIO> mIOList;
        
        public App()
        {
            mIOList = new List<IIO>();
            
            mIOList.Add(new IO1( ... ));
            mIOList.Add(new IO2( ... ));
        }
    }
}


Hoe kan ik nu in de onderliggende DLLs de interface bekend maken? Als hij alleen gedefinieerd is in de applicatie, of alleen in de DLLs, kent een van beide het type niet.
Ik heb geprobeerd om exact dezelfde interface definitie (dus in dezelfde namespace en dezelfde naam) óók in de DLL te zetten, maar dan krijg ik compiler fouten. Dit is eigenlijk de manier zoals C++ het doet met de header files.

De manieren die ik heb gevonden zijn:
  • De interface in een losse assembly, dus in een los project zetten en in alle betrokken projecten een reference toevoegen.
  • [i]Dit werkt, maar je krijg een ontzettende grote brei aan DLL files en aan vooral aan onderlinge references binnen projecten. Eigenlijk geen oplossing.[/i]
  • Met reflection het type "converteren" en voor alle interfaces een wrapper schrijven.
  • [i]Ook dit werkt, maar de nadelen zijn wel duidelijk denk ik. Je gebruikt reflection, je creeërt een overhead aan wrappers en ook dit levert extra DLLs op.[/i]
Info:
http://gsraj.tripod.com/dotnet/reflection.html
Interfaces dynamisch gebruiken m.b.v. reflection

http://stackoverflow.com/...e-in-different-assemblies
Interface definiëren in een losse assembly

http://stackoverflow.com/...de-contracts-in-interface
Code contracts. Wellicht is dit iets, maar dit zegt mij niet veel |:(

Hoe krijg ik in C# nou die mooie type overlap die de C++ linker zo goed voor elkaar krijgt? :)

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Ik zou toch gaan aan een losse assembly voor de interface(s). Waarom zou dat een "grote brei aan DLL files" geven? Die dll's die de interface uit "myinterfaces.dll" implementeren zullen toch enigszins gerelateerd zijn aan elkaar; in 't ergste geval krijg je dan dus a.dll, b.dll, c.dll, ... die je anders toch al hebt en de enige extra dll is dan de myinterfaces.dll.

De enige manier om de "extra" dll te "besparen" is wanneer je kunt zeggen: a.dll is altijd nodig, b.dll, c.dll, ... zijn optioneel. Dan kun je b, c, ... laten verwijzen naar interfaces uit a.

[ Voor 20% gewijzigd door RobIII op 01-09-2011 23:58 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ja, er is niets mis met type libraries, want dat is in feite gewoon wat het is. Die dient als referentie voor zowel de app als alle DLLs. Er is geen brei, je hebt gewoon 1 DLL met je interfaces. Dit is gewoon de standaard manier om dit soort dingen te doen.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • hell4you
  • Registratie: Mei 2006
  • Laatst online: 16:36
Nou, wellicht is mijn verhaal niet compleet. Die interfaces zijn uiteindelijk geimplementeerd in C++. Hiervoor wordt een P/Invoke wrapper geschreven. (Dus 1 managed wrapper en een unmanaged implementatie). Daar komt dus nog een DLL bij voor de interface. Op zich valt hier nog mee te leven, maar ik zit met een applicatie met zo'n 10 interfaces.. x 3 = 30 DLLs.

Maar goed, vergeet dat hierboven maar even. Qua project references bedoel ik het volgende.. Stel je hebt dit design (niet álle pijlen zijn getekend om het overzicht te behouden):

Afbeeldingslocatie: http://i51.tinypic.com/2d6tdn9.png

- De blauwe vakken zijn assemblies. (+ de application natuurlijk)
- De rode pijlen zijn project references.

De IIOControl wordt voor een specifieke fabrikant geimplementeerd en geeft daarvoor generieke IInputs en IOutputs terug.

Er zijn zoveel project references, omdat je een lager type(bijv. IInput) niet dóór een .NET dll kan exporteren (zover ik weet). Dat betekent dat de applicatie naar zowel de hoogste DLL als alle onderliggende DLLs moet refereren.

Nja, in C++ zou dit hele verhaal in plaats van 3 DLLs, een enkele zijn. Waarom dan geen C++? Nou, er zit een geavanceerde (WPF) GUI bij. En sommige interfaces zijn al native geimplementeerd in .NET.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

Die interfaces zijn uiteindelijk geimplementeerd in C++. Hiervoor wordt een P/Invoke wrapper geschreven. (Dus 1 managed wrapper en een unmanaged implementatie)
Dat hoeven iig al niet 2 DLL's te zijn als je gewoon gebruik maakt van C++/CLI. Native en managed code kun je op die manier in 1 DLL stoppen. Is tevens ook efficienter dan P/Invoke (en imho een stuk makkelijker te implementeren)
Daar komt dus nog een DLL bij voor de interface. Op zich valt hier nog mee te leven, maar ik zit met een applicatie met zo'n 10 interfaces.. x 3 = 30 DLLs.
Ik zie niet in waarom elke interface zijn eigen DLL moet krijgen eigenlijk. Maak gewoon 1 grote assembly met álle interface definities.
De IIOControl wordt voor een specifieke fabrikant geimplementeerd en geeft daarvoor generieke IInputs en IOutputs terug.
Wat levert die fabrikant dan, sourcecode of een assembly? En als ie een assembly levert, dan levert ie dus ook de assembly waar IInput en IOutput in gedefinieerd staat?

Overigens, je bent op de hoogte van het feit dat je assemblies gewoon kunt mergen? (Dat werkt dan weer niet voor WPF overigens, dus die zul je dan hoe dan ook apart moeten houden)

[ Voor 6% gewijzigd door .oisyn op 02-09-2011 01:53 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • hell4you
  • Registratie: Mei 2006
  • Laatst online: 16:36
.oisyn schreef op vrijdag 02 september 2011 @ 01:48:
Dat hoeven iig al niet 2 DLL's te zijn als je gewoon gebruik maakt van C++/CLI. Native en managed code kun je op die manier in 1 DLL stoppen. Is tevens ook efficienter dan P/Invoke (en imho een stuk makkelijker te implementeren)
Ja, je zou inderdaad met managed C++ een wrapper kunnen maken. Maar dan heb je toch nog steeds een unmanaged DLL en een managed dll (wrapper)? Anders kun je de wrapper weer niet in C# gebruiken.
.oisyn schreef op vrijdag 02 september 2011 @ 01:48:
Ik zie niet in waarom elke interface zijn eigen DLL moet krijgen eigenlijk. Maak gewoon 1 grote assembly met álle interface definities.
Maar dan is het niet mogelijk om later netjes de componenten te kiezen die je nodig hebt, en daar alleen de interfaces van te hebben. (Nouja, je zou wellicht voor iedere applicate een andere verzamel DLL kunnen bouwen)
.oisyn schreef op vrijdag 02 september 2011 @ 01:48:
Wat levert die fabrikant dan, sourcecode of een assembly? En als ie een assembly levert, dan levert ie dus ook de assembly waar IInput en IOutput in gedefinieerd staat?
Nee, de fabrikant levert de hardware. En de implementatie verschilt, maar het gebruik ervan is gelijk.
.oisyn schreef op vrijdag 02 september 2011 @ 01:48:
Overigens, je bent op de hoogte van het feit dat je assemblies gewoon kunt mergen? (Dat werkt dan weer niet voor WPF overigens, dus die zul je dan hoe dan ook apart moeten houden)
Ja inderdaad. Ik zie eerlijk gezegd die interfaces.dll ook als een soort "pre-compiled header", al is dat een beetje vreemd ;)

Ik denk dat ik ga voor één interfaces dll waarin ik de sources van elk te gebruiken component in include. :)

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

hell4you schreef op vrijdag 02 september 2011 @ 08:20:
[...]


Ja, je zou inderdaad met managed C++ een wrapper kunnen maken. Maar dan heb je toch nog steeds een unmanaged DLL en een managed dll (wrapper)? Anders kun je de wrapper weer niet in C# gebruiken.
Mijn punt is dus dat dat niet zo is :). Je kunt gewoon een .Net assembly hebben in een DLL waar ook native code in staat.

C++/CLI is trouwens wat anders dan managed C++, die laatste is deprecated. Maar tot zover de terminologie, jij zult waarschijnlijk ook wel gewoon C++/CLI bedoelen en niet die managed extensions die je in VC++ 2003 nog had.
Maar dan is het niet mogelijk om later netjes de componenten te kiezen die je nodig hebt, en daar alleen de interfaces van te hebben. (Nouja, je zou wellicht voor iedere applicate een andere verzamel DLL kunnen bouwen)
Dat laatste idd. Ik zie niet helemaal in wat precies het probleem is van het referencen van een assembly waar je niet alles van gebruikt.

[ Voor 12% gewijzigd door .oisyn op 02-09-2011 11:58 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
.oisyn schreef op vrijdag 02 september 2011 @ 10:50:
[...]
Dat laatste idd. Ik zie niet helemaal in wat precies het probleem is van het referencen van een assembly waar je niet alles van gebruikt.
Inderdaad, en eventueel kun je de interfaces nog netjes groeperen in 2 of meer libraries zodat het logisch gegroepeerd is.

Het hebben van meerdere DLL's of DLL's waar je niet alles van gebruikt is namelijk helemaal niet erg.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Av3ng3rtje
  • Registratie: December 2002
  • Laatst online: 18-08 10:15
Misschien is MEF iets voor je:

http://www.pnpguidance.ne...FrameworkTutorialMEF.aspx

Kan je alle DLL's in een keer inladen. Interface zou ik een aparte assembly houden.

Acties:
  • 0 Henk 'm!

  • urk_forever
  • Registratie: Juni 2001
  • Laatst online: 17-09 15:08
Av3ng3rtje schreef op vrijdag 02 september 2011 @ 12:04:
Misschien is MEF iets voor je:

http://www.pnpguidance.ne...FrameworkTutorialMEF.aspx

Kan je alle DLL's in een keer inladen. Interface zou ik een aparte assembly houden.
En anders heb je ook nog MAF. Om het overzichtelijk te houden :P

[ Voor 9% gewijzigd door urk_forever op 02-09-2011 12:16 ]

Hail to the king baby!


Acties:
  • 0 Henk 'm!

  • hell4you
  • Registratie: Mei 2006
  • Laatst online: 16:36
.oisyn schreef op vrijdag 02 september 2011 @ 10:50:
Mijn punt is dus dat dat niet zo is :). Je kunt gewoon een .Net assembly hebben in een DLL waar ook native code in staat.
Juist. Dit wist ik wel, maar besefte ik even niet :z Maar ok, het blijven 2 losse DLLs want de optie moet open blijven om de implmentatie in unmanaged code te kunnen blijven gebruiken.
.oisyn schreef op vrijdag 02 september 2011 @ 10:50:
C++/CLI is trouwens wat anders dan managed C++, die laatste is deprecated. Maar tot zover de terminologie, jij zult waarschijnlijk ook wel gewoon C++/CLI bedoelen en niet die managed extensions die je in VC++ 2003 nog had.
Klopt. Ik bedoel een (v10) Visual C++ CLR project en de daarin ingebouwde features.
.oisyn schreef op vrijdag 02 september 2011 @ 10:50:
Dat laatste idd. Ik zie niet helemaal in wat precies het probleem is van het referencen van een assembly waar je niet alles van gebruikt.
Hmm, waarom ook niet. Er zit zelfs helemaal geen implementatie in. Ik zie het nu inderdaad als een soort SDK DLL die je niet volledig gebruikt.
Av3ng3rtje schreef op vrijdag 02 september 2011 @ 12:04:
Misschien is MEF iets voor je:
Kan je alle DLL's in een keer inladen. Interface zou ik een aparte assembly houden.
Ziet er leuk uit, maar ik heb meer verschillende interfaces dan implementaties. Zo wordt testability, maintainability enz... een stuk beter. MEF en MAF lijkt me meer handig voor een dynamisch plugin systeem.

Acties:
  • 0 Henk 'm!

  • [ti]
  • Registratie: Februari 2000
  • Niet online
MEF en MAF zijn twee verschillende dingen: MAF gebruik je voornamelijk voor isolatie/veiligheid (addins draaien in eigen appdomein) en versioning, MEF gebruik je weer voor compositie. Aan de hand van de openingspost zou ik naar MEF gaan kijken, is wel pas vanaf v4.0 ingebakken in het framework, maar op codeplex is wel een versie voor 3.5 te vinden.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 17-09 14:05

.oisyn

Moderator Devschuur®

Demotivational Speaker

hell4you schreef op vrijdag 02 september 2011 @ 13:08:
[...]

Juist. Dit wist ik wel, maar besefte ik even niet :z Maar ok, het blijven 2 losse DLLs want de optie moet open blijven om de implmentatie in unmanaged code te kunnen blijven gebruiken.
En zelfs dat kan ook gewoon als het in 1 DLL staat. Fantastisch he, dat .Net :P

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • hell4you
  • Registratie: Mei 2006
  • Laatst online: 16:36
.oisyn schreef op vrijdag 02 september 2011 @ 13:26:
En zelfs dat kan ook gewoon als het in 1 DLL staat. Fantastisch he, dat .Net :P
Dat wist ik niet!
[ti] schreef op vrijdag 02 september 2011 @ 13:10:
Aan de hand van de openingspost zou ik naar MEF gaan kijken, is wel pas vanaf v4.0 ingebakken in het framework, maar op codeplex is wel een versie voor 3.5 te vinden.
Ik zal eens op onderzoek uit gaan :)

Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
RobIII schreef op donderdag 01 september 2011 @ 23:54:
Ik zou toch gaan aan een losse assembly voor de interface(s). Waarom zou dat een "grote brei aan DLL files" geven?
Idd. Wel eens gezien hoeveel jar files een gemiddelde java app meelevert? Wat boeit dat nu.

https://niels.nu

Pagina: 1