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();
}
}
Related
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.
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.
I have been Googling for hours and cant find an article that is exactly related to what I need.
I have a MVC4 site with the following layers:
Presentation layer (MVC4)
Business Layer
Data layer
I want to use the following provider:(installed using NuGet)
Install-Package Microsoft.AspNet.Providers
My question is more of an architectural one.
In my mind, I should install this (Microsoft.AspNet.Providers) in my data layer as it is code that talks to a membership database.
All the posts I can find, however, even by Hanselman just install it in the Presentation layer / MVC4.
I am very big on separation of concerns and am using dependency injection throughout my application.
Obviously I need the config for the provider in my web.config but want all the membership code in my data layer.
Any thoughts?
thanks
RuSs
PS. Would love to know the process of installing this in a data / repository layer using nuget. Slightly confused as to what DLLs Nuget is installing. If I install in my data layer, nuget doesnt update the MVC web.config.
The answer is quite simple actually: You should hide the providers behind an abstraction that you define in your business layer. This way you can write an adapter that implements this abstraction an wraps the provider and you can inject this adapter into your business layer using dependency injection. This way you will only have to reference the Microsoft.AspNet.Providers from your MVC4 project, and prevent any code from directly referencing the AspNet.Providers, which allows you to switch more easily later on.
Example:
// Define in business layer
public interface IAuthorizationService
{
bool bool IsCurrentUserInRole(string role);
}
public class SomeBusinessLayerCommand
{
private IAuthorizationService authorizer;
public SomeBusinessLayerCommand(
IAuthorizationService authorizer)
{
this.authorizer = authorizer;
}
public void SomeOperation()
{
if (this.authorizer.UserIsInRole("Admins"))
{
// some secret admin stuf
}
else
{
// some normal user stuf
}
}
}
And in your Presentation Layer you can define an adapter:
public class MembershipAdapter : IAuthorizationService
{
public bool IsCurrentUserInRole(string role)
{
return Roles.IsUserInRole(role);
}
}
And you can map IAuthorizationService to MembershipAdapter using your favorite DI container.
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.