I have a Xamarin forms app that is using dryioc for IoC. It seems all my services get disposed as soon as the view is out of scope
This is how I am registering the service in the app.cs
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IInboxService, InboxService>();;
}
and I resolve it this way in the app.cs
protected override void OnInitialized()
{
_started = DateTime.Now;
InitializeComponent();
InitializeAppSettings();
Container.Resolve<ISyncService>().Init(new List<ISyncableService>
{
Container.Resolve<IInboxService>()
});
}
When I need to use it in a viewmodel I put it in the constructor like so.
public class HomeViewModel {
public HomeViewModel(InboxService inboxService)
{
}
}
The singleton is respected but then it will dispose and create a new one when it needs it. Anyone else run into this ?
Xamarin Version: 5.0.0.2125
Prism Version: 8.1.97
LocIOS Version: 8.1.97
public HomeViewModel(InboxService inboxService)
This injects a concrete InboxService instance, which is independent of the registration of interfaces that it might implement. If you want your singleton, request an IInboxService:
public HomeViewModel(IInboxService inboxService)
I try to give a service implementing a certain interface a meaningful name that's more than just interface's name minus I, like DummyInboxService, TestInboxService, ImapInboxService, Pop3InboxService, RemoteInboxService... thus making clearer what the respective implementation actually does and helping finding these errors (most likely a typo anyway) early.
Related
My Prism 7.1 application uses 2 modules like plugins.
The App : PrismApplication registers a IDataService singleton that is always available
protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IDataService, DataService>();
}
and both plugins can use it
public void OnInitialized(IContainerProvider containerProvider)
{
_dataService = containerProvider.Resolve<IDataService>();
}
This is OK - both modules get the same instance of the object.
But:
Each of the two plugins also needs to use IUsbStatus singleton, but the main application does NOT know about it, I register it in the MyModuleA : IModule and also in MyModuleB : IModule:
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterSingleton<IUsbStatus, UsbStatus>();
}
If I only use plugin A or plugin B, everything works fine, but if I use both plugins, then the IUsbStatus singleton is registered twice and when I resolve it, it does NOT give me the same instance of the object.
How can I fix this?
You have to check whether the singleton is already registering before overriding the existing registration. Or you have to make sure to not resolve anything before everything is registered.
The latter option is clearly preferable but more difficult to achieve, so just check before registering the UsbStatus. The IContainerRegistry cannot do that, so you have to get your actual container and do some container-specific stuff, e.g. for unity:
using Prism.Unity;
[...]
if (!containerRegistry.GetContainer().IsRegistered<IUsbStatus>())
containerRegistry.RegisterSingleton<IUsbStatus, UsbStatus>();
I have an application that creates a lifetime scope at some point like so:
public class Main
{
public void Main()
{
using (ILifetimeScope scope = AutofacContainer.Container.BeginLifetimeScope())
{
scope.Resolve<SomeClass>();
}
}
}
Within SomeClass I have logic which then calls a lot of different classes and so on..
Then, about 10 methods down the call stack I need to use the main scope to do this:
public class ActivatorFactory : IActivatorFactory
{
public T Create<T>(Type instance)
{
using (ILifetimeScope scope = AutofacContainer.Container.BeginLifetimeScope())
{
return (T)scope.Resolve(instance);
}
}
}
The problem with that is that now I've created a new scope which is just used to resolve a runtime type. I want to be able to use the main scope to resolve this type. How can I do so without passing the main scope down to this factory class through 10 different methods/functions?
The only "hacky" solution I thought of is to just have a static property on my ActivatorFactory and set the scope in my Main class like so:
public class Main
{
public void Main()
{
using (ILifetimeScope scope = AutofacContainer.Container.BeginLifetimeScope())
{
ActivatorFactory.Scope = scope;
scope.Resolve<SomeClass>();
}
}
}
Is there a cleaner solution to use the main scope in another part of my application?
I had this need for a CancellationTokenSource instance per lifetime scope, where children are linked to their parent. If the the root scope's CancellationTokenSource, is canceled, all children lifetime scope's CancellationToken are canceled. To accomplish this, I created:
private sealed class ParentLifetimeScopeAccessor
{
private readonly ILifetimeScope _lifetimeScope;
public ParentLifetimeScopeAccessor(ILifetimeScope lifetimeScope)
{
_lifetimeScope = lifetimeScope;
_lifetimeScope.ChildLifetimeScopeBeginning += OnChildLifetimeScopeBeginning;
}
public ILifetimeScope ParentLifetimeScope { get; private set; }
private void OnChildLifetimeScopeBeginning(object sender, LifetimeScopeBeginningEventArgs e) =>
e.LifetimeScope.Resolve<ParentLifetimeScopeAccessor>().ParentLifetimeScope = _lifetimeScope;
}
With a registration, you can now access your parent's scope:
builder.RegisterType<ParentLifetimeScopeAccessor>().InstancePerLifetimeScope();
With the parent lifetime scope accessor, linked CancellationTokenSource instances can be created:
private static CancellationTokenSource CancellationTokenSourceFactory(IComponentContext context)
{
var scopeAccessor = context.Resolve<ParentLifetimeScopeAccessor>();
var parentScope = scopeAccessor.ParentLifetimeScope;
return null == parentScope
? new CancellationTokenSource()
: CancellationTokenSource.CreateLinkedTokenSource(parentScope.Resolve<CancellationTokenSource>().Token);
}
CancellationToken resolver:
private static CancellationToken CancellationTokenResolver(IComponentContext context) =>
context.Resolve<CancellationTokenSource>().Token;
Two registrations:
builder.Register(CancellationTokenSourceFactory).AsSelf().InstancePerLifetimeScope();
builder.Register(CancellationTokenResolver).AsSelf().InstancePerDependency();
If you're not using ActivatorFactory for your app (and you shouldn't be if you're using inversion of control) then delete it and think about what you're trying to test.
Are you trying to test that you can generally just resolve things from Autofac? Autofac has a raft of unit tests as well as millions of successful users. No value in testing the framework.
Are you trying to test that you registered all the things you needed to register? There's not a lot of value in that, either, for a couple of reasons: first, you'll hit that at runtime pretty quickly and see it in those tests; second, in a large, decoupled system those tests get really stale really quickly. It's a maintenance hassle.
Are you trying to test that a specific object graph can be composed based on your registrations? I might buy this one. See below.
Let's say it's the last thing - you have a really complex and troublesome object graph you want to ensure you can create because people keep breaking it. I could see that.
Separate your registrations out into an Autofac module. Use the Autofac module to test.
public class MyRegistrations : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Thing>();
// and all your other registrations.
}
}
then in the unit test
var builder = new ContainerBuilder();
builder.RegisterModule<MyRegistrations>();
var container = builder.Build();
var thing = container.Resolve<Thing>();
// Assert on the resolved thing.
You can use that same module to encapsulate your registrations in the app and then you'll actually be testing the complex registration but without a factory you're not using.
Warning: It is a slippery slope between testing some complex registration and testing all registrations. Like I said, you really don't want to test every registration you have. I've fallen down this slope. It's a maintenance nightmare. Add a registration to the module/app, add a test. Uh oh, we refactored, now the registrations are all different. Ugh. That's less testing about behavior than about characterization (not "what do I want it to do" but "what does it do now"). Pain. Suffering.
If you are using ActivatorFactory in your app for, say, service location instead of using some more standard thing like CommonServiceLocator that already does that for you and for which Autofac already directly integrates... then just test ActivatorFactory with a real container but with some arbitrary test registrations rather than the whole set from the real app. The functionality of ActivatorFactory doesn't have any bearing on what's registered inside it.
And, yeah, if you're using ActivatorFactory and need to keep it around, you'll have to hand it an ILifetimeScope at app startup. That's how service locators work. You'll see that all over in the Autofac docs when you look at how to integrate with apps like ASP.NET, WCF, and others.
I'm building a program on Unity 5 and Prism 7. I want my program to be highly modular so I want it to behave correctly if some modules are unavailable.
For this I want to mark optional dependencies with [OptionalDependency] attribute and let a classes with them to decide themselves what to do if there's null passed in constructor.
But if I mark a dependency with this attribute, Unity doesn't resolve it and just pass null instead of dependency instance, despite the module is available as usual.
How do I make dependency as really nice to have?
Or another option, how do I make Unity to not throw when dependency cannot be resolved, and just pass null instead and let the constructing classes decide what to do?
There's App.xaml.cs of my program:
public partial class App : PrismApplication
{
protected override Window CreateShell()
{
InitializeModules();
this.ShutdownMode = ShutdownMode.OnMainWindowClose;
var shell = Container.Resolve<Shell>();
this.MainWindow = shell;
return shell;
}
protected override void RegisterTypes(IContainerRegistry containerRegistry) { }
/// <summary>
/// Creating catalog of Modules from .dlls in "Modules" folder
/// </summary>
protected override IModuleCatalog CreateModuleCatalog()
{
var catalog = new DirectoryModuleCatalog() { ModulePath = #"./Modules" };
catalog.Initialize();
// by the way, modules aren't getting recognized without
// catalog.Initialize() or InitializeModules in CreateShell.
// Should it be such as that? Seems to me like no..
return catalog;
}
}
Beside main question, I appreciate any suggestions on how to make my code better in the comments under the question, because I'm a noob in Prism+Unity. Thank you!
This approach is not a good idea. Constructor injection means that the dependencies are required. Also, I don't think the OptionalDependencyAttribute works in the ctor, but rather must be applied to a property. Try making a property and applying the attribute to it.
All the code in the CreateShell method is not needed. Just return Container.Resolve<Shell>() and that's it.
Also, the modules not loading is a bug which was fixed and is available in the latest Prism CI biuld on MyGet.
I have a problem that I don't know how to solve. I have a container which contains different interfaces for different services that I expose with a WebApi. The problem is that I need to get that dependencies inside my controller and I must avoid the use of static. I read about this
http://beletsky.net/2011/10/inside-aspnet-mvc-idependencyresolver.html
http://www.asp.net/web-api/overview/advanced/dependency-injection
In the asp.net I read that I can implement my own IDependencyResolver. Is this madness? because I searched a lot and I only found examples using Unity. If I don't want to use that dependency injector? What it's the best way to achieve this?.
public class MyController: ApiController
{
private InterfaceService m_interfaceService; //This is the dependency I need
public MyController()
{
}
[HttpGet]
[Route("myServices/")]
public List<IServiceCategory> GetServiceObjectsList()
{
return m_interfaceServices.GetObjectsList();
}
}
So you have an pre-existing container/dependency mechanism! You should ask your team why it was a good idea to make something like that instead of using all the good ones out in the .net world.
Nonetheless, from the docs:
http://www.asp.net/web-api/overview/advanced/dependency-injection
Although you could write a complete IDependencyResolver implementation
from scratch, the interface is really designed to act as bridge
between Web API and existing IoC containers.
The Unity example on that page shows what must be done to bridge the gap between Unity DI framework and the web mvc. You just need to do the same thing with your home-rolled one. It's matter of implementing just a few methods. Go for it!
Here is an implementation that meets your requirements:
namespace AdvancedDI.Controllers
{
public class ProductController : ApiController
{
public IFactory iFactory { get; set; }
protected override void Initialize(HttpControllerContext controllerContext)
{
DIAPP.GetContainer(this);
base.Initialize(controllerContext);
}
public IHttpActionResult Get()
{
var response = iFactory.DoWork();
return Ok(response);
}
protected override void Dispose(bool disposing)
{
DIAPP.Dispose(this);
base.Dispose(disposing);
}
}
}
This is one kind of property based injection. It is possible with UnityContainerExtensions. The Initialize method will get called before Get.
Step 1. DIAPP.GetContainer(this) carries the entire productController context.
Step 2. GetContainer receives the IFactory property information from this.
Step 3. Next, you have a chance to receive the unity IBuilderContext for this IFactory.
I've used both Ninject and AutoFac for dependency injection. This is not madness, it's common practice.
I've been trying to inject the modules from my ModuleCatalog into my Shell's ViewModel but I'm not having much luck...
I'm creating the ModuleCatalog in my Bootstrapper and my module is getting onto the screen from its Initializer without problem. However, I'd love to be able to bind my list of modules to a container with a DataTemplate which allowed them to be launched from a menu!
Here's my Boostrapper file, I'll be adding more modules as times goes on, but for now, it just contains my rather contrived "ProductAModule":
public class Bootstrapper : UnityBootstrapper
{
protected override void ConfigureContainer()
{
Container.RegisterType<IProductModule>();
base.ConfigureContainer();
}
protected override IModuleCatalog GetModuleCatalog()
{
return new ModuleCatalog()
.AddModule(typeof(ProductAModule));
}
protected override DependencyObject CreateShell()
{
var view = Container.Resolve<ShellView>();
var viewModel = Container.Resolve<ShellViewModel>();
view.DataContext = viewModel;
view.Show();
return view;
}
}
Following on from that, here's my Shell's ViewModel:
public class ShellViewModel : ViewModelBase
{
public List<IProductModule> Modules { get; set; }
public ShellViewModel(List<IProductModule> modules)
{
modules.Sort((a, b) => a.Name.CompareTo(b));
Modules = modules;
}
}
As you can see, I'm attempting to inject a List of IProductModule (to which ProductAModule inherits some of its properties and methods) so that it can then be bound to my Shell's View. Is there something REALLY simple I'm missing or can it not be done using the Unity IoC? (I've seen it done with StructureMap's extension for Prism)
One more thing... When running the application, at the point the ShellViewModel is being resolved by the Container in the Bootstrapper, I receive the following exception:
Resolution of the dependency failed, type = "PrismBasic.Shell.ViewModels.ShellViewModel", name = "". Exception message is: The current build operation (build key Build Key[PrismBasic.Shell.ViewModels.ShellViewModel, null]) failed: The parameter modules could not be resolved when attempting to call constructor PrismBasic.Shell.ViewModels.ShellViewModel(System.Collections.Generic.List`1[[PrismBasic.ModuleBase.IProductModule, PrismBasic.ModuleBase, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]] modules). (Strategy type BuildPlanStrategy, index 3)
Anyway, simple huh... Looks bemused...
Any help would be greatly appreciated!
Rob
I think you could probably just do this:
public class Bootstrapper : UnityBootstrapper
{
protected override void ConfigureContainer()
{
Container.RegisterType<IProductModule>();
base.ConfigureContainer();
}
private static ObservableCollection<IProductModule> _productModules = new Obser...();
public static ObservableCollection<IProductModule> ProductModules
{
get { return _productModules; }
}
protected override IModuleCatalog GetModuleCatalog()
{
var modCatalog = new ModuleCatalog()
.AddModule(typeof(ProductAModule));
//TODO: add all modules to ProductModules collection
return modCatalog;
}
...
}
Then you would have a static property that anything could bind to directly, or could be used from your ViewModel.
Here is how to get a list of module names that have been registered with the module catalog.
public class MyViewModel : ViewModel
{
public ObservableCollection<string> ModuleNames { ... }
public MyViewModel(IModuleCatalog catalog)
{
ModuleNames = new ObservableCollection<string>(catalog.Modules.Select(mod => mod.ModuleName));
}
}
That's pretty much it. IModuleCatalog and IModuleManager are the only things that are setup in the container for you to access in terms of the modules. As I said, though, you won't get any instance data because these modules (hopefully) are yet to be created. You can only access Type data.
Hope this helps.
I think you misunderstood the purpose of the modules. The modules are just containers for the views and services that you wish too use. The shell on the other hand should just contain the main layout of your application.
What I think you should do is to define a region in your shell, and then register the views (which in your case are buttons) with that region.
How you wish do deploy your views and services in terms of modules is more related to what level of modularity you're looking for, i.e. if you want to be able to deploy the views and services of ModuleA independently of the views and services of ModuleB and so on. In your case it might be enough to register everything in one single module.
Take some time to play around with the examples provided with the documentation, they are quite good.
The reason why your examples throws an example is because your ShellViewModel is depending on List and that type is not registered in Unity. Furthermore you're registering IProductModule with Unity, which makes no sense because an Interface cannot be constructed.
I think I encountered a similar problem today, it turns out that PRISM creates the shell before initializing the modules, so you can't inject any services from the modules into the shell itself.
Try creating another module that depends on all of the others and implements the functionality you want, then you can add it to a region in the shell to display your list of services. Unfortunately I haven't had a chance to try it yet, but this is the solution I plan on implementing.
As a side note, I think you need to mark the property with an attribute to use property injection, but I could be mistake (it's been a while since I played with Unity directly).
Edit: You need to apply the DependencyAttribute to properties to use setter injection in Unity; you can read about it here.
var modules = new IProductModule[]
{
Container.Resolve<ProductAModule>()
//Add more modules here...
};
Container.RegisterInstance<IProductModule[]>(modules);
That's it! Using this code, I can inject my modules into the ShellViewModel and display each module as a button in my application!
SUCH a simple resolution! From a great guy on the CompositeWPF Discussion group. I recommend them without reserve ^_^