UPDATE
Ok, uparłem się, trochę pogrzebałem, i udało mi się znaleźć jak to zrobić. W zasadzie to nie znalazłem bezpośredniego rozwiązania, ale zainspirował mnie ten artykuł oraz ta odpowiedź na SO.
Generalnie rzecz biorąc to chodzi tu o to, żeby ukryć zależności biblioteki przed projektem aplikacji. W przeciwnym wypadku projekt aplikacji będzie płakał wyjątkami, że zależności biblioteki nie zostały zarejestrowane w kontenerze aplikacji. A tak naprawdę zostały już zarejestrowane w kontenerze biblioteki, choć są wstrzyknięte do konstruktora biblioteki dostępnego publicznie, przez to widzi je też aplikacja.
Jak ktoś poradził na SO, z pomocą tu przychodzi wzorzec fasady. Należy w nim schować zależności i rozwiązać Resolve
fasadę w klasie biblioteki dostępnej z projektu aplikacji. Prosty przykład poniżej, w którym warstwę serwisową zarejestrowałem jako singletony:
public class Booter
{
public static IContainer BootStrap()
{
var builder = new ContainerBuilder();
builder.RegisterType<FilesService>()
.As<IFilesService>().SingleInstance();
builder.RegisterType<ControlsService>()
.As<IControlsService>().SingleInstance();
builder.RegisterType<Facade>()
.AsSelf().SingleInstance();
return builder.Build();
}
}
Do fasady wstrzykujemy wszystkie zależności biblioteki:
public class Facade
{
IFilesService _fileService;
IControlsService _controlsService;
public Facade(IFilesService filesService, IControlsService controlsService)
{
_fileService = filesService;
_controlsService = controlsService;
FilesService = _fileService;
ControlsService = _controlsService;
}
public IFilesService FilesService { get; }
public IControlsService ControlsService { get; }
}
Następnie w naszej bibliotece najpierw wołamy metodę Initialize
, w której rozwiązujemy fasadę, a następnie do interfejsów serwisów przypisuję własności fasady wstrzykniętych już serwisów:
public class MainService : IMainService
{
IFilesService _fileService;
IControlsService _controlsService;
IContainer _container;
public MainService()
{
Initialize();
}
public void Initialize()
{
_container = Booter.BootStrap();
var aggregator = _container.Resolve<Facade>();
_fileService = aggregator.FilesService;
_controlsService = aggregator.ControlsService;
}
public UiControlsModel SwitchOff()
{
return _controlsService.SwitchOff();
}
public UiControlsModel SwitchOn()
{
return _controlsService.SwitchOn();
}
}
Mam nadzieję że nie jest to żaden antywzorzec.