Cannot implement YouTube Android Player API with Mvvm Model xamarin - xamarin.android

I need to use YouTubePlayerView to play Youtube Video in my mvvm crossplatform project. The problem is: my view needs to inherit 2 classes while C# does not allow multiple inheritance:
VideoDetailView.cs
public class VideoDetailView : MvxAppCompatActivity, YouTubeBaseActivity
{
}
YouTubeBaseActivity to use Google Player API, to use a YouTubePlayerView, your activity must extend YouTubeBaseActivity.
MvxAppCompatActivity to be able to bind View with ViewModel.
Have been stuck in this issue for couple days, I need help!
Thanks

To implement this feature, you can create MvxYouTubeBaseActivity:
MvxYouTubeBaseActivity : YouTubeBaseActivity, IMvxEventSourceActivity, IMvxAndroidView
{
protected MvxYouTubeBaseActivity()
{
BindingContext = new MvxAndroidBindingContext(this, this);
this.AddEventListeners();
}
//Implement all methods from IMvxEventSourceActivity, IMvxAndroidView
}
And create MvxYouTubeBaseActivity<TViewModel.>:
public abstract class MvxYouTubeBaseActivity<TViewModel>: MvxYouTubeBaseActivity, IMvxAndroidView<TViewModel>
where TViewModel : class, IMvxViewModel
{
protected MvxYouTubeBaseActivity(IntPtr ptr, JniHandleOwnership ownership)
: base(ptr, ownership)
{
}
protected MvxYouTubeBaseActivity()
{
}
public new TViewModel ViewModel
{
get => (TViewModel)base.ViewModel;
set => base.ViewModel = value;
}
}
That's all, you can use it with MVVMCross

Related

android MVP & DI

I am creating an android app and I write following classes and interface and codes .Because I try to use MVP pattern , But now I am not sure that my codes are standard or not ?
should I use Dagger2 for Di or should not?
model , presenter class are below:
public class ChangePasswordModel{
public void saveChange(final String oldPass, final String newPass, final ChangePasswordCallback callback) {
/*in real world it change password with API*/
callback.onDo();
} }
my presenter is :
public class ChangePasswordPresenter{
private ChangePasswordContract.View mView;//this is an interface to interact with Activity
public ChangePasswordPresenter(ChangePasswordContract.View mView) {
this.mView = mView;
}
public void pSaveChange(String oldPass, String newPass) {
ChangePasswordModel model = new ChangePasswordModel();
model.saveChange(oldPass, newPass, new ChangePasswordCallback() {
#Override
public void onDo() {
mView.showMessage("password Changed");
}
});
}
}
Do I implemented MVP correctly?
Should I use Dagger2 for DI? why?
The sample codes that you mentioned in your question is a correct implementation of MVP which can get improved by some changes.
The best practice is a mixture of Dagger, MVP, RxJava, Retrofit and Mock tests which improve the quality and readability of your project. MVP helps you with a clean and separate layered code and RxJava will help with wiring different layers up together and Dagger2 can really helps you with managing dependencies and also make your Mocking in test easy.
You can take a look at this sample project repo on my Github which has been developed using Dagger, MVP and there are also some test available:
http://github.com/mmirhoseini/fyber_mobile_offers
It needs to be improved in my opinion. You Model class must be a concrete object class however your ChangePasswordModel contains saveChange() method that have no idea why it's calling a callback. This logic must be implemented in Presenter class.
Basically process of following MVP design pattern is as follows:
create a package based on your screen. Let's say you have a Signup screen. Then create a package, <your.main.package>.signupscreen.
Create three classes of SignupActivity, SignupView(this is interface), SignupPresenter.
SignupView interface:
interface SignUpView {
String getFirstName();
String getLastName();
String getEmailAddress();
String getPassword();
}
SignupActivity implements SignUpView and holds a reference of SignupPresenter.
public class SignUpActivity implements SignUpView {
#Inject
public Service mService;
SignUpPresenter mSignUpPresenter;
#Override
protected void onStart() {
super.onStart();
mSignUpPresenter = new SignUpPresenter(mService, this);
}
#Override
protected void onStop() {
super.onStop();
if (mSignUpPresenter != null) {
mSignUpPresenter.onStop();
}
}
#Override
public String getFirstName() {
return etFirstName.getText().toString().trim();
}
#Override
public String getLastName() {
return etLastName.getText().toString().trim();
}
#Override
public String getEmailAddress() {
return etEmail.getText().toString().trim();
}
#Override
public String getPassword() {
return etPassword.getText().toString().trim();
}
}
And finally SignupPresenter class:
class SignUpPresenter implements SignUpCallback {
private final Service service;
private final SignUpView view;
private CompositeSubscription subscriptions;
SignUpPresenter(Service service, SignUpView view) {
this.service = service;
this.view = view;
this.subscriptions = new CompositeSubscription();
}
void onStop() {
subscriptions.unsubscribe();
}
}
This is very basic implementation of Activity based on MVP. I do recommend to have a look at this awesome doc regard MVP, Retrofit and Dagger 2, A Simple Android Apps with MVP, Dagger, RxJava, and Retrofit

AutoFac Register confusion

Hi I am just been looking at AutoFac and following their getting-started tutorial
http://autofac.readthedocs.org/en/latest/getting-started/index.html
having followed it and understanding how their services work I wanted to try to create a new implementation on the same interface type
builder.RegisterType<TodayWriter>().As<IDateWriter>();
builder.RegisterType<TomorrowWriter>().As<IDateWriter>();
Both implentations contain the same code
public class TomorrowWriter : IDateWriter
{
private IOutput _output;
public TomorrowWriter(IOutput output)
{
this._output = output;
}
public void WriteDate()
{
this._output.Write(DateTime.Today.AddDays(1).ToShortDateString());
}
}
So TodaysWriter is the same apart from the WriteDate method displaying
this._output.Write(DateTime.Today.ToShortDateString());
instead.
So now using the application, how do I determine what implementation to use as both methods are called WriteDate()
using(var scope = Container.BeginLifetimeScope())
{
var writer = scope.Resolve<IDateWriter>();
// Is this using todaysWriter or TomorrowWriter?
writer.WriteDate();
}
Am I using this wrong?
Thanks
To differentiate between different implementations of the same interface look at named and keyed services in the docs.
Alternatively you can roll your own by registering a DateWriterFactory and having a method on that to get a specific IDateWriter implementation. something like:
public class DateWriterFactory
{
IDateWriter GetWriter(string writerName)
{
if (writername=="TodayWriter")
return new TodayWriter();
if (writername=="TomorrowWriter")
return new TomorrowWriter();
}
}
obviously the implementation of the factory could be as complex or as simple as you need. Or you could just have methods to get the fixed writers rather than pass in a string.

Where can I initialize AutoMapper mappings in an Orchard module?

I am busy developing my first non-example Orchard module. It is a handful of controllers and views, with custom (EF) data access, and is largely independent of Orchard content types and parts. Normally I set up mappings in an Application_Start handler, but as the actions in this MVC module will be invoked in the context of the Orchard application, I no longer have that point of entry. My most obvious and immediate solution is to move mapping initialization into static constructors for mapped view models, e.g.
public class ApplicantPersonalDetailsModel : MappedViewModel<Applicant>
{
static ApplicantPersonalDetailsModel()
{
Mapper.CreateMap<Applicant, ApplicantPersonalDetailsModel>().Bidirectional();
}
....
}
How else can I do this? is there a better way to do this in MVC3/4 in general, or preferably, an event or hook I can grab in the Orchard application to also achieve this on applicaion startup?
The way I have done it is by implementing IOrchardShellEvents
public class MenuOrchardShellEvents : IOrchardShellEvents
{
public void Activated()
{
Mapper.CreateMap<YSRB.Menu.Models.Records.Customer, YSRB.Menu.Models.ViewModels.CustomerViewModel>()
.ForMember(c => c.CustomerType,
m => m.MapFrom(
x => (CustomerTypes)x.CustomerType
)
);
Mapper.CreateMap<YSRB.Menu.Models.ViewModels.CustomerViewModel, YSRB.Menu.Models.Records.Customer>()
.ForMember(c => c.CustomerType,
m => m.MapFrom(
x => (int)x.CustomerType
)
);
}
public void Terminating()
{
//Do nothing
}
}
Hope this helps.
The Handler is the best place for initializing your variables, even if you haven't defined any part inside your module you can define one without a driver but with handler.
public class InitPartHandler : ContentHandler
{
public InitPartHandler(IRepository<InitPartRecord> repository)
{
OnInitializing<InitPart>((context, part) =>
// do your initialization here
);
}
}
EDIT
InitPart and InitPartRecord would be
public class InitPart : ContentPart<InitPartRecord>
{
}
public class InitPartRecord : ContentPartRecord
{
}

How to inject dependencies in Collection form?

How do I wire up dependencies where the dependency is in the form of a collection ??
For Example:
public class Ninja {
public List<IShuriken> Shurikens {get;set;}
public IKatana Katana {get;set;}
public void Attack()
{
// some code goes here to use weapons and kill people
}
}
How do i use a container like Ninject in a case like this ??
EDIT: I am not talking specifically about Ninject but thats the DI/IOC I use the most. :)
You can Bind a closed type List<X> ToConstant(), ToMethod() etc.
But you'd have to supply more detail as to what you want in the list or I'd just be engaging in idle speculation as to exactly what you want.
EDIT in response to yours and your comment: If you're dealing with 'Unknown' or loose dependencies, then MEF does lots of stuff in that direction.
[In general with DI] If you're doing something internally and it's a more 'Known' / fixed / complex resolution mechanism, you're better off modelling something like this by having a Repository or other coordinating object that will manage the list that you can request subsets and/or other projections of on an as-needed basis.
[If you're interested in specific mechanisms in Niject] You'd be crazy not to download the source and do a grep/FIF/Shift-Ctrl-Q for List to find out the real story though - the code is clean and neat and the Tests provide examples.
For example, you can Bind multiple items to an interface and then have them added into a collection for you automatically:-
namespace Ninject.Tests.Integration.EnumerableDependenciesTests {
public class WhenServiceRequestsUnconstrainedListOfDependencies
{
[Fact]
public void ServiceIsInjectedWithListOfAllAvailableDependencies()
{
kernel.Bind<IParent>().To<RequestsList>();
kernel.Bind<IChild>().To<ChildA>();
kernel.Bind<IChild>().To<ChildB>();
var parent = kernel.Get<IParent>();
VerifyInjection( parent );
}
protected override void VerifyInjection( IParent parent )
{
parent.ShouldNotBeNull();
parent.Children.ShouldNotBeNull();
parent.Children.Count.ShouldBe( 2 );
parent.Children[0].ShouldBeInstanceOf<ChildA>();
parent.Children[1].ShouldBeInstanceOf<ChildB>();
}
}
public class RequestsList : IParent
{
public IList<IChild> Children { get; private set; }
public RequestsList( List<IChild> children )
{
Children = children;
}
}
public interface IChild { }
public class ChildA : IChild { }
public class ChildB : IChild { }
public interface IParent
{
IList<IChild> Children { get; }
}
}
In Autofac you'd use an IEnumerable constructor dependency:
public class Ninja {
public Ninja(IEnumerable<IShuriken> shurikens, IKatana katana)
{
// ...
}
Autofac will find any available shurikens and provide them to the constructor automatically.
I don't know about Ninject. in Castle Windsor, you'd use ListResolver and that would provide all implementations of IShuriken.

How do I handle classes with static methods with Ninject?

How do I handle classes with static methods with Ninject?
That is, in C# one can not have static methods in an interface, and Ninject works on the basis of using interfaces?
My use case is a class that I would like it to have a static method to create an
unpopulated instance of itself.
EDIT 1
Just to add an example in the TopologyImp class, in the GetRootNodes() method, how would I create some iNode classes to return? Would I construct these with normal code practice or would I somehow use Ninject? But if I use the container to create then haven't I given this library knowledge of the IOC then?
public interface ITopology
{
List<INode> GetRootNodes();
}
public class TopologyImp : ITopology
{
public List<INode> GetRootNodes()
{
List<INode> result = new List<INode>();
// Need code here to create some instances, but how to without knowledge of the container?
// e.g. want to create a few INode instances and add them to the list and then return the list
}
}
public interface INode
{
// Parameters
long Id { get; set; }
string Name { get; set; }
}
class NodeImp : INode
{
public long Id
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public string Name
{
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
}
// Just background to highlight the fact I'm using Ninject fine to inject ITopology
public partial class Form1 : Form
{
private ITopology _top;
public Form1()
{
IKernel kernal = new StandardKernel(new TopologyModule());
_top = kernal.Get<ITopology>();
InitializeComponent();
}
}
If you're building a singleton or something of that nature and trying to inject dependencies, typically you instead write your code as a normal class, without trying to put in lots of (probably incorrect) code managing the singleton and instead register the object InSingletonScope (v2 - you didnt mention your Ninject version). Each time you do that, you have one less class that doesnt surface its dependencies.
If you're feeling especially bloody-minded and are certain that you want to go against that general flow, the main tools Ninject gives you is Kernel.Inject, which one can use after you (or someone else) has newd up an instance to inject the dependencies. But then to locate one's Kernelm you're typically going to be using a Service Locator, which is likely to cause as much of a mess as it is likely to solve.
EDIT: Thanks for following up - I see what you're after. Here's a hacky way to approximate the autofac automatic factory mechanism :-
/// <summary>
/// Ugly example of a not-very-automatic factory in Ninject
/// </summary>
class AutomaticFactoriesInNinject
{
class Node
{
}
class NodeFactory
{
public NodeFactory( Func<Node> createNode )
{
_createNode = createNode;
}
Func<Node> _createNode;
public Node GenerateTree()
{
return _createNode();
}
}
internal class Module : NinjectModule
{
public override void Load()
{
Bind<Func<Node>>().ToMethod( context => () => Kernel.Get<Node>() );
}
}
[Fact]
public void CanGenerate()
{
var kernel = new StandardKernel( new Module() );
var result = kernel.Get<NodeFactory>().GenerateTree();
Assert.IsType<Node>( result );
}
}
The ToMethod stuff is a specific application of the ToProvider pattern -- here's how you'd do the same thing via that route:-
...
class NodeProvider : IProvider
{
public Type Type
{
get { return typeof(Node); }
}
public object Create( IContext context )
{
return context.Kernel.Get<Node>();
}
}
internal class Module : NinjectModule
{
public override void Load()
{
Bind<Func<Node>>().ToProvider<NodeProvider>();
}
}
...
I have not thought this through though and am not recommending this as A Good Idea - there may be far better ways of structuring something like this. #Mark Seemann? :P
I believe Unity and MEF also support things in this direction (keywords: automatic factory, Func)
EDIT 2: Shorter syntax if you're willing to use container-specific attributes and drop to property injection (even if Ninject allows you to override the specific attributes, I much prefer constructor injection):
class NodeFactory
{
[Inject]
public Func<Node> NodeFactory { private get; set; }
public Node GenerateTree()
{
return NodeFactory();
}
}
EDIT 3: You also need to be aware of this Ninject Module by #Remo Gloor which is slated to be in the 2.4 release
EDIT 4: Also overlapping, but not directly relevant is the fact that in Ninject, you can request an IKernel in your ctor/properties and have that injected (but that doesn't work directly in a static method).

Resources