Functionality of Prism modules in interested classes (Xamarin Foirms + Prism) - xamarin.forms

Good day!
UPDATE
I don’t understand how to access the functionality of the Prism module from the class using the module logic.
Questions:
How do I get access to the implementation of the IServiceA functionality (defined in the module) in PageAViewModel, which I forget to do?
How can I manage the life of ModuleA / ServiceA if I want to use this functionality on a number of different countries, without loading the module every time (scenario - I call ModuleA / ServiceA when loading an application, use it on PageA / PageB / PageC, after using it I unload it) .
Thank you all for any answers!
Have a nice day!
/Sorry for google translate/

The modules of a prism application are for modularizing the code base. They have nothing to do with views or view models, but rather splitting the application up into components that can be independently developed and tested and replaced. How you split your application is up to you.
Probably you should review the documentation chapter about modularity...
Edit: about the concret questions:
How do I get access to the implementation of the IServiceA functionality (defined in the module) in PageAViewModel, which I forget to do?
You create a constructor parameter of type IService and prism will provide you with the registered implementation:
internal class PageAViewModel
{
public PageAViewModel( IService service )
{
service.DoStuff();
}
}
How can I manage the life of ModuleA / ServiceA if I want to use this functionality on a number of different countries, without loading the module every time
You cannot and need not manage the lifetime of ModuleA, prism takes care of that. As for, ServiceA you chose a lifetime when registering:
containerRegistry.Register<IService, ServiceA>() creates a new service instance for each page
containerRegistry.RegisterSingleton<IService, ServiceA>() create a single service instance for all the pages

Related

F#: How to test internal modules from another project?

I follow the best F# practices from .Net documentation:
I create a project for the Application (console, not library)
I create a project for the Tests (with Expecto but doesn't matter)
Problem: Some of my Application modules are not exposed via the internal keyword. Thus I cannot import these modules in my Tests project.
=> How can I perform unit testing of these modules? Should I remove the internal access control?
Thanks!
To test internal, you can use InternalsVisibleTo, to test private classes, you can link the files in your test project (when you are in the "add file" dialog, you can select link, instead of open).
However, as already has been commented, generally you would only test the public interface. But occasionally you want to separately test complex internals as well. For instance in the .NET runtime libraries, this is often done (there are a lot of complex internals), and they use the linking approach a lot.
Since private really means private to the class, and you won't even be able to access such members from an extension method, you should put such members in their own private class, as public members. That way, when you link, the class is accessible, and the members as well, but neither are accessible in your production version.
Use this technique sparingly, because it will bind your private details to the test system, and you won't be as free to change the internal implementation.

How to create individual dll of asp.net mvc project pages? [duplicate]

I'm just learning asp.net mvc and I'm trying to figure out how to move my controllers into a separate project. Typically when I have designed asp.net web apps before, I created one project for my models, another for my logic, and then there was the web.
Now that I'm learning asp.net mvc I was hoping to follow a similar pattern and put the models and controllers each into their own separate projects, and just leave the views/scripts/css in the web. The models part was easy, but what I don't understand is how to make my controllers in a separate project be "found". Also, I would like to know if this is advisable. Thanks!
First of all, it is certainly a good idea to put your model into a separate project. As you've discovered, this is trivial.
Regarding Controllers and Views, I don't see any obvious advantage to separating them for most basic projects, although you may have a particular need to do so in a particular application.
If you do choose to do this, then you will need to tell the framework how to find your controllers. The basic way to do this is by supplying your own ControllerFactory. You can take a look at the source code for the DefaultControllerFactory to get an idea for how this is done. Subtyping this class and overriding the GetControllerType(string controllerName) method may be enough to accomplish what you're asking.
Once you've created your own custom ControllerFactory, you add the following line to Application_Start in global.asax to tell the framework where to find it:
ControllerBuilder.Current.SetControllerFactory(new MyControllerFactory());
Update: Read this post and the posts it links to for more info. See also Phil Haack's comment on that post about:
ControllerBuilder.Current.DefaultNamespaces.Add(
"ExternalAssembly.Controllers");
...which is not a complete solution, but possibly good enough for simple cases.
While it is reasonable to create your own ControllerFactory, I found it more convenient to define all my Controllers in each project, but derive them from Controllers in my Shared project:
namespace MyProject1.Controllers
{
public class MyController : MySharedProject.Controllers.MyController
{
// nothing much to do here...
}
}
namespace MySharedProject.Controllers
{
public abstract class MyController : System.Web.Mvc.Controller
{
// all (or most) of my controller logic here...
}
}
This has the added benefit that you have a place to put your Controller logic that differs from project to project. Also, it is easier for other developers to quickly find your Controller logic because the Controllers exist in the standard place.
Regarding whether this is advisable, I think it absolutely is. I've created some common Account Management logic that I want to share between projects that otherwise have very different business logic. So I'm sharing my Account and Admin Controllers, but the other Controllers are specific to their respective projects.
Add the Class Library for your mvc project.
In the class add the following code(For u'r Controller Code)
namespace ContactController
{
public class ContactController : Controller
{
public ActionResult Call()
{
ViewBag.Title = "Inside MyFirst Controller.";
return View();
}
}
}
On the mvc project view folder add the folder for Contact and create a Call.cshtml file.
Add the class library project reference into your main MVC project.
Finally to refer contact controller namespace into Route Config.
My problem solved after I updated System.Web.Mvc NuGet reference so MvcWebsite and Class Library use same System.Web.Mvc version
No need to add default namespaces
The simplest form of separation I use is to retain the Views "as is" in the original MVC project but remove the Controllers. Then in a new ClassLibrary project add the Controller classes and ensure they inherit from Controller.
The MVC routing engine will automatically route to the Controllers in the ClassLibrary and the Controllers will automatically construct the Views from the original MVC project, provided you have your references and usings correctly in place.
I am using this architecture to implement an Html Reports module that can be compiled and deployed separately from the main solution. At last I am free from SSRS!

MvvmCross MvxApplication class overriding for different platforms. (Plus, encryption)

I've got two questions here. The first one is just specific and another one is more general, but is a source of the first one.
So, my specific problem: I want to use Encryption (actually, Hashing) algorithms with using System.Security.Cryptography namespace (for instance, SHA256Managed class).
I found out that (happily) Xamarin has implemented those in System.dll.
But it is not portable and obviously can not be used from Core application directly.
But I've also found another great project -- PclContrib -- which allows you to do that. But, unfortunately, they don't have the implementation for Touch and Android. (However, that still works great for Desktop (Web) and Windows Phone, plus, still can be included into Core (as it uses portable project)).
Anyway, to solve that nicely, I've decided to create some base class for the encryption methods and then override core methods which require the custom dll (for any custom system).
The way I did it (at least, trying to do) was:
Defining virtual method in Core App base class:
public virtual IEncryptionProvider CreateEncryptionProvider()
Overriding Core App class in Touch project with overriding CreateEncryptionProvider (which creates an instance of TouchEncryptionProvider class instance).
Core:
public class App : MvxApplication
Touch:
public class AppTouch : App
Launching it in Touch setup.cs:
protected override Cirrious.MvvmCross.ViewModels.IMvxApplication CreateApp (
{
return new AppTouch();
}
But, that does not work for me. On startup I've got this exception message in log:
"Exception masked KeyNotFoundException: Could not find view for Mynamespace.Etc.LoginViewModel", which works fine when I do new App() instead. I am not sure if that message shows actual problem (as before it was saying the same even that was a problem with some third-party dll, unrelated to views at all). But speaking shortly, that's just a primitive inheritance of App : MvxApplication, but placed not in Core but Touch project.
So, does it requeire some more custom initialization for such situations or do I miss something else?
And, actually, more general question is how should I build such Multiplatform approaches? Actually, now I've got similar problem with HttpUtility.UrlEncode, which I would want to use in my Core project.
What is the MvvmCross "philosophy" to handle such situations?
Thank you.
For the 'viewmodel not found' problem, this is caused because mvvmcross by default only looks for viewmodels in the Assembly containing your app.
If you want it to look in other assemblies, override ViewModelAssemblies in Setup.cs - see how this done in, for example, MvvmCross - structuring shared View Models and Views
For general multplatform approach, please read questions and answers like:
Platform-specific IoC in MVVMCross
Instantiation of ViewModels and Service classes
Please also remember you don't have to use PCLs - if you prefer to use file-linking between multiple platform-specific core projects, then you can of course use this approach.
Finally, please also try to ask one question per question - I find it makes stackoverflow work better for users and with search engines too. If you need to link questions, then you can just add a hyperlink reference - stackoverflow then marks them as related.

Symfony2 where to place custom helper classes

I'm starting with a Symfony2 project. I know the framework basics but I have a question:
Where is the right place to pot those helper classes I create for help or for the business logic?
Max's answer is correct. However I question the path he recommends for your code.
The following classes and files have specific emplacements:
Service Container Extensions (belong in) DependencyInjection/
from http://symfony.com/doc/current/cookbook/bundles/best_practices.html
That says your Services should be placed in a folder called 'DependencyInjection', not 'Services'. In full, it should be src/Foo/BarBundle/DependencyInjection
I say this as someone that had the former and has just finished moving them all to the latter (!)
What #Adam says is wrong, you have to store your Dependency Injection Extensions in DependecyInjection directory, not the services itself. In the documentation says that you can store your (custom) business logic classes in any place you like.
http://symfony.com/doc/current/best_practices/business-logic.html
The best way to keep the business logic is create service to handle all the logic. So it will be in:
src/Foo/BarBundle/Service
and you need to call the service in the services.yml.
I recently did some small work on an existing Symfony2 project. As described by answer from Tuong Le, I created my Helper classes under the Helper directory of the bundle and class name with Helper suffix i.e. the helper class is located at:
src/MyBundle/Helper/MyUtilHelper.php
I can use MyUtilHelper class in my bundle without calling the service container i.e. I didn't need to call.
$container->get('my_util');
I don't really know whether there is some special config. in my setup; someone already got it setup and I was just adding new functionality.
You can create the custom classes under your Bundle, such as under a folder Helper/..
However, to use those helper in your code, you'll need to define those Helper(s) in your service description file (such as services.xml)... Then you can use $container->get('your_helper')->
According to official documentation - in particular - Symfony Best Practices - you should store your services in Utils folder under the src. I belive, that this is correct way regardless of whether you want or don't wont to make the functionality provided by services of your bundle available to other parts of application via Service Container. Furthermore, you can store helper classes in any place you consider suitable. Concerning #Adam Knowles and #PachinSV answers - they are not quite right because they do not answer your question - "Where is the right place to pot those helper classes I create for help or for the business logic?" or "Where to store classes which I want to register and use via Service Container" - but not where to put bundle Extension class - which main purpose is to provide information about configuration which should be automatically loaded from your bundle to apps Service Container during the process of booting the Kernel.

Ninject.Web (webforms extension), injecting outside of a webform page?

I've been using the Ninject.Web extension to inject business objects, repositories, Entity Framework context etc into my application. This works very well using the [Inject] attribute which can be applied within a webform that inherits from PageBase. I am now running into a snag as I am trying to write a custom membership provider that needs injection done inside of it but of course this provider is not instantiated from within a webform. Forms Authentication will instantiate the object when it needs it. I am unsure how to about doing this without having access to the [Inject] attribute. I understand that there is an application level kernel somewhere, but I have no idea how to tap into it. Any suggestions would be greatly appreciated.
You don't have to use the service locator pattern, just inject into properties of your custom membership provider in Application_Start. Assuming you've registed the providers properly you can do this with something like:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
// Inject account repository into our custom membership & role providers.
_kernel.Inject(Membership.Provider);
// Register the Object Id binder.
ModelBinders.Binders.Add(typeof(ObjectId), new ObjectIdModelBinder());
}
I've written up a more in depth explanation here:
http://www.danharman.net/2011/06/23/asp-net-mvc-3-custom-membership-provider-with-repository-injection/
You do a IKernel.Inject on the the instance. Have a look at the source for the Application class in the extension project you're using.
In the case of V2, it's in a KernelContainer. So you need to do a:
KernelContainer.Inject( this )
where this is the non-page, non application class of which you speak.
You'll need to make sure this only happens once - be careful doing this in Global, which may get instantiated multiple times.
Also, your Application / Global class needs to derive from NinjectHttpAppplication, but I'm sure you've that covered.
you may need to use the Service Locator pattern, since you have no control over the creation of the membership provider.

Resources