UnityContainer und interner Konstruktor

8

Ich habe eine Klasse mit internem Konstruktor und möchte sie von Unity (2.0) lösen.

%Vor%

Dann mache ich

%Vor%

Wenn ich das tue, habe ich eine Ausnahme

%Vor%

IService ist registriert und das einzige Problem ist, dass der Konstruktor intern ist. Ich möchte wirklich, dass diese Klasse öffentlich ist, aber ich möchte, dass sie nur über eine Factory erstellt werden kann (in der ich tatsächlich container.Resolve<MyClass>() anrufe).

Gibt es eine Möglichkeit, Unity diesen internen Konstruktor anzeigen zu lassen? Wie InternalsVisibleTo oder etwas?

    
Shaddix 20.06.2011, 13:48
quelle

4 Antworten

8

Ich habe ein wenig darüber nachgedacht, wie Sie Unity für diesen Zweck erweitern könnten, und einige interessante Informationen gefunden.

Zuerst scheint es so zu sein, dass Unity den zu verwendenden Konstruktor auswählt, indem er intern IConstructorSelectorPolicy auflöst. In Unity ist die public abstract class ConstructorSelectorPolicyBase<TInjectionConstructorMarkerAttribute> enthalten, die dieses Juwel enthält:

%Vor%

FindInjectionConstructor und company sind private static -Methoden in dieser Klasse, die letztendlich zu Type.GetConstructors aufrufen (die Überladung ohne Parameter, die nur public -Konstruktoren zurückgibt). Das sagt mir, dass Sie, wenn Sie dafür sorgen können, dass Unity Ihre eigene Konstruktorauswahl-Richtlinie verwendet, die in der Lage wäre, einen beliebigen Konstruktor auszuwählen, golden sind.

Es gibt eine gute Dokumentation zum Thema und wie Verwenden Sie Ihre eigenen Container-Erweiterungen, also stelle ich mir vor, dass es durchaus möglich ist, Ihre eigene CustomConstructorSelectorPolicy zu erstellen, die die relevanten Teile von DefaultUnityConstructorSelectorPolicy (das von der abstrakten Basisklasse abgeleitet ist und der Standard ist, sofern Sie nicht etwas anderes registrieren) und ConstructorSelectorPolicyBase (direkt davon abgeleitet würde wahrscheinlich nicht gut funktionieren, da Schlüsselmethoden nicht virtual sind, aber Sie können den Code wiederverwenden).

Daher würde ich sagen, dass es mit einem moderaten Aufwand machbar ist, aber das Endergebnis wäre aus technischer Sicht ziemlich "rein".

    
Jon 20.06.2011, 14:30
quelle
6

Unity sieht nur öffentliche Konstruktoren an, daher müssen Sie diesen Konstruktor öffentlich machen.

  

Ich möchte wirklich, dass diese Klasse öffentlich ist,   aber ich möchte, dass es nur via erstellt werden kann   eine Fabrik

In diesem Fall erstellen Sie eine Factory:

%Vor%

Und registrieren:

%Vor%

Und lösen:

%Vor%

Sie können auch Unity InjectionFactory :

verwenden %Vor%

Damit dies funktioniert, sollte die Assembly, die diesen Code enthält, die Interna der Assembly sehen können, die MyClass enthält. Mit anderen Worten, die MyClass Assembly sollte mit InternalsVisibleTo markiert werden.

Was auch funktionieren würde, ist folgendes:

%Vor%

Obwohl Sie den Konstruktor nicht öffentlich machen müssen, ist es eine gute Möglichkeit, Ihren Code zu verschleiern: -)

    
Steven 20.06.2011 14:17
quelle
2

Machen Sie die Klasse intern und den Konstruktor public ...

  1. Schnittstelle public
  2. Klasse intern
  3. Konstruktor der Klasse public.
Razer 29.11.2011 16:12
quelle
0

Es ist möglich, dass es Workarounds / Hacks gibt, die es Ihnen erlauben würden, dies mit Unity 9 zu tun. Ich weiß nicht, ob), aber im Allgemeinen, wenn eine Klasse von Unity (oder einem beliebigen IOC-Container) verwaltet werden soll mit einem öffentlichen Konstruktor öffentlich sein.

Eine Option könnte darin bestehen, eine abstrakte Factory zu erstellen, die die Klasse mit einem öffentlichen Konstruktor erstellt, und den Konstruktor der Klasse intern zu halten. Der Nachteil ist, dass Ihre Fabrik von Unity verwaltet wird, aber Ihre Klasse selbst nicht.

    
Phil Sandler 20.06.2011 14:15
quelle