Im currently working on a DDD layer architecture. I am not sure how to use Dependency Injection on Android project solution. Currently my Android solution holds a reference to class library solution. I have used Unity on my service layer and register container via WebApiConfig.cs.
My question is, how do i go about using Unity on Android side in order to run on start up, would be grateful if code was included. I dont want to new-up the container through main activity of Android. I want the container to register behind the process i.e. AppStart or Global asax where it does it for you for MVC apps. Is there a way to do it for Android?
Also I noticed on Main Activity I am unable to create constructor. I guess this isnt possible but how do I go about holding object reference to my Class Library solution ? example that i attempted to do:
private IExample _ex;
MainActivity(IExample ex){
_ex = ex; //depedency Injection rather than newing it up
}
public void DoSomething(){
_ex.HelloWorld();
}
Also for each of my layer do I need to install and create container in order to resolve current solution dependency ? or can I use container from android which would resolve all dependency in each layer as DDD goes from outer to inner ?
Old question, but for future readers:
Subclassing the application class would do what you are after in regard to registering the container at start up.
[Application]
public class App : Application
{
public static UnityContainer Container { get; set; }
public App( IntPtr javaRef, JniHandleOwnership transfer ) : base( javaRef, transfer )
{
}
public override void OnCreate( )
{
base.OnCreate( );
Container = new UnityContainer( );
Container.RegisterType<ISomeService, ServiceImplementation>( );
}
}
Application Class:
https://developer.xamarin.com/api/type/Android.App.Application/
That's all I can offer at this stage... I'm still in the process of implementing a full Xam.Android solution with Unity & new to dependency injection in general.
Related
I'm writing a cross platform Xamarin background application and want to use Shiny.
I have got a service interface and platform specific concrete implementations of the class.
I'm sure its something simple but the piece of the puzzle I am missing is how to register the interface in the Shiny DI container so that the correct platform specific implementation is used.
If I was doing this without Shiny I would have my own DI container in the App class and initialise that from each platform. With Shiny, I only seem to have the ShinyStart class where I can get to the services collection but that does not have access to the concrete classes.
I have looked into Shiny modules but cannot figure out from the documentation how they get around the issue either
How do I get access to the Shiny DI service container from within platform specific code so I can register the correct concrete class against the interface?
Regards
Brian
If anybody else is interested in this I found the answer buried in the shiny code. You have to define a MainApplication class and use RegeisterPlatformServices.
public partial class MainApplication : global::Android.App.Application
{
public MainApplication(IntPtr handle, JniHandleOwnership transfer) :
base(handle, transfer) {}
public override void OnCreate()
{
this.ShinyOnCreate(new global::ElevateNfc.ShinyStartup
{
RegisterPlatformServices = services =>
{
services.AddSingleton<IManager, Manager>();
}
});
global::Xamarin.Essentials.Platform.Init(this);
base.OnCreate();
}
}
I am not sure how to use Dependency Injection on Xamarin Android project solution. Currently my Android solution holds a reference to another class library solution. I have used Unity on my service layer and registered the container via WebApiConfig.cs.
My question is, how do i go about using Unity on Android side in order to run on start up, would be grateful if code was included. I dont want to new-up the container through main activity of Android. I want the container to register behind the process i.e. AppStart or Global asax where it does it for you for MVC apps. Is there a way to do it for Android? Also I noticed on Main Activity I am unable to create constructor. I guess this isnt possible but how do I go about holding object reference to my Class Library solution ? example that i attempted to do:
private IExample _ex;
MainActivity(IExample ex){
_ex = ex; //depedency Injection rather than newing it up
}
public void DoSomething(){
_ex.HelloWorld();
}
Is there a way to do it via Attribute ? Also for each of my layer do I need to install and create container in order to resolve current solution dependency ? or can I use container from android which would resolve all dependency in each layer as DDD architecture goes from outer to inner ?
In terms of setting up DI at startup you can create a custom Application implementation like so:
// Must include this attribute so that Android knows we want to use this as our Application implementation
[Application(Icon = "#drawable/Icon", Label = "#string/ApplicationName")]
public class MyApplication : Application
{
public override void OnCreate()
{
base.OnCreate();
// Do your DI initialization/registration here
}
}
I'm not sure exactly what you mean by not being able to create a constructor on the main activity. You can create constructors for any activity you feel like. You don't always see it though because people tend to put their initialization logic in OnCreate.
In normal ASP.MVC projects we configure the dependency resolver with Unity and the Unity.Mvc3 package from http://unitymvc3.codeplex.com/
We have this test service registered with a HierarchicalLifetimeManager
container.RegisterType<ITestService, TestService>(new HierarchicalLifetimeManager());
And we hook up the container with Mvc in Global.asax.cs:
System.Web.Mvc.DependencyResolver.SetResolver(new Unity.Mvc3.UnityDependencyResolver(container));
And we run this test controller:
public class TestController : Controller
{
private readonly ITestService _service;
public TestController(ITestService service)
{
this._service = service;
}
public ActionResult Test()
{
var locatedService = System.Web.Mvc.DependencyResolver.Current.GetService<ITestService>();
if (_service == locatedService)
return View("Success - Same Service");//This is always the result in an MVC controller
else
throw new Exception("Failure - Different Service Located");//This is never the result in an MVC controller
}
}
However, on this project we are adding a number of WebAPI controllers.
We have this configuration in global.asax.cs (using http://unitywebapi.codeplex.com/ for now. But I am open to suggestions):
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = new Unity.WebApi.UnityDependencyResolver(container);
We have created an ApiTestController similar to TestController inheriting from ApiController rather than from Controller.
However, the ApiTestController fails its test. I understand that the System.Web.Mvc.DependencyResolver class and the System.Web.Mvc.DependencyResolver.Current property are specific to Mvc. But does WebAPI have an equivalent?
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver.GetService does not work because the System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver instance is the parent container that I configured. It is not the child controller that was used to inject the ITestService into the constructor.
This user seems to have a similar problem: http://unitywebapi.codeplex.com/discussions/359413
But I feel that this probably has more to do with ASP.NET's WebAPI than it has to do with Unity.
Thanks
After looking over the source of http://unitymvc3.codeplex.com/ and http://unitywebapi.codeplex.com/ I created this class:
public class MyUnityDependencyResolver : Unity.Mvc3.UnityDependencyResolver, System.Web.Http.Dependencies.IDependencyResolver
{
public MyUnityDependencyResolver(IUnityContainer container)
: base(container)
{
}
public System.Web.Http.Dependencies.IDependencyScope BeginScope()
{
return this;
}
public void Dispose()
{
Unity.Mvc3.UnityDependencyResolver.DisposeOfChildContainer();
}
}
Configuration in gobal.asax.cs:
var myResolver = new MyUnityDependencyResolver(container);
System.Web.Mvc.DependencyResolver.SetResolver(myResolver);
System.Web.Http.GlobalConfiguration.Configuration.DependencyResolver = myResolver;
Unity.Mvc3.UnityDependencyResolver uses HttpContext.Current.Items to manage child containers. MyUnityDependencyResolver may not be the most "correct" implementation of System.Web.Http.Dependencies.IDependencyResolver, but it seems to work so far.
I will mark this as the answer in a couple days if no one else has any better answers.
Unfortunately, when you call the GlobalConfiguration.Configuration.DependencyResolver.GetService, it completely ignores any scope and resolves using the outer non-child container which is around for the lifetime of the application. This is an issue with Web Api and makes it impossible to use constructor injection for per-request dependencies outside of controllers. Confusingly this is completely different behaviour from MVC as you say.
What you can do is use the GetDependencyScope() extension method off HttpRequestMessage. Anything you resolve using this will be in per request scope when using HierarchicalLifetimeManager in conjunction with Unity.WebApi. The request is available from action filters and handlers so may be a viable workaround.
Obviously this is pure service location rather than dependency injection which is far from ideal but I have not found another way to access per-request dependencies outside of controllers.
See this post for more info.
The DependencyResolver is not the right seam for dependency injection in ASP.NET WebAPI.
Mark Seemann has two really good posts on DI with WebAPI.
Dependency Injection and Lifetime Management with ASP.NET Web API
Dependency Injection in ASP.NET Web API with Castle Windsor
If you want to do it right you should have a look at them.
i'm trying to solve a problem with the Autofac IoC container.
My web application has the following parts:
Web application
Core (shared) library.
Modules
Each module has a reference to the core library (that includes the code below) and each module must be able to register their own types. Therefore i need to have one shared container between application and modules.
I have the following container's code:
public static class DependencyContainer
{
public static IContainer Container { get; private set; }
public static ContainerBuilder Builder { get; private set; }
public static void RegisterType<TFrom, TTo>() where TTo : TFrom
{
Builder.RegisterType<TTo>().As<TFrom>();
}
public static T ResolveType<T>()
{
return Container.Resolve<T>();
}
public static void InitContainer()
{
Builder = new ContainerBuilder();
Container = Builder.Build();
}
}
This container is located in the main (core) library. When application starts it calls InitContainer() from global.asax. After this i'm trying to register a new type from my application modules using RegisterType() method.
But after this i can not resolve any types. It just throws an exception that this type wasn't registered.
The main idea of this code is that i'm going to be able to resolve any type from any module and web application using only one shared container.
Can somebody help me with this problem? Is there a more elegant architectural solution for using one shared IoC container between multiple libraries?
Thanks in advance!
Your design leads to the Service Locator anti-pattern. Prevent from defining a container in the core library and letting everybody reference it. Use dependency injection and configure the container in the Composition Root, your start-up path of the application (in your case the composition root will be part of your Web Application).
You can take advantage of the Autofac Module feature, and in the composition root, you can register this module.
builder.RegisterModule(new CarTransportModule());
But you can define your module registration classes as static as well, which is even simpler:
MyApp.SomeModule.SomeModuleBootstrapper.Register(builder);
Problem solved - we need to call container.Build() only AFTER registration of all our dependencies...
What is the recommended way to set up / inject dependencies in a viewModel after tombstoning given that when the app deactivates you typically add the ViewModel to the State dictionary and then before your app reactivates the framework deserialises the ViewModel which requires a default constructor?
If I have the class below, I would like to have dependency injection create an instance of "MyVM" injecting the dependencies for IServiceA and IServiceB. Having a default constructor would not set up the requried dependecies.
public class MyVM(IServiceA svca,IServiceB svcB)
{
}
How should the ViewModel be setup in a tombstoning scenario here?
I don't know if you're using a specific MVVM framework but Caliburn Micro has some built in features for tombstoning.
A little snippet from the docs:
public class PivotPageModelStorage : StorageHandler<PivotPageViewModel> {
public override void Configure() {
this.ActiveItemIndex()
.InPhoneState()
.RestoreAfterViewLoad();
}
}
That example is storing the ActiveItemIndex, a property on PiveotPageViewModel, in phone state but it can also store entire object graphs in PhoneState, AppSettings, or your own custom implementation. You get all that by inheriting from StorageHandler. With CM you don't have to worry about re-injecting services, it will handle that for you as it has it's own built in container.
CM WP7 Docs
In a recent Hanselman post about building a WP7 app he talked a bit about TombstoneHelper. I haven't used this one but it looks interesting.