We have an ASP.NET Web API app which uses Ninject for DI. This works perfect for use. One of the improvements we were considering is the ability to swap out parts of functionality per request based on some sort of unique identifier.
Example. Two customers use our restful api. Both get the same functionality. A third customer has paid for the super version of our api. He makes the request, we load the super dll and bind the super implementations to the standard interfaces.
Essentially what I am looking to see is can we load a DLL and swap out bindings per request using Web API and Ninject.
EDIT:
So both answers are correct for the original question but my intention is different and it is my fault for not explaining it correctly. What we have is a base layer of functionality that everyone gets. On top of this we also have the ability to implement custom logic on a per customer basis that overrides this functionality. This logic is stored as a DLL in Azure Blob Storage.
What we would like to do is when a customer makes a request is go get the DLL, bind all the custom services and then service the request using these new bindings.
Is hot swapping not the best way to do this? We are new enough to ninject so this may be a common thing that is implemented in a different way to what we are considering.
To some up, we would like to be able to service custom bindings on a per customer basis.
EDIT 2:
We use conditional bindings for items were we know that we have alternate implementations but in the scenario above until we get the customer info and scan the dll we do not know if we have alternate bindings. We don't even know if there is a dll.
We would like to do it this way so we can drop the file in rather than referencing it in the project.
I don't mind that you can swap out bindings per request. But what you can do is to use conditional binding.
Example - default bindings:
protected override Ninject.IKernel CreateKernel()
{
var kernel = new StandardKernel();
kernel.Bind<IAuthorizationService>()
.To<AuthorizationService>()
.InRequestScope();
kernel.Bind<IService>()
.To<BasicService>();
return kernel;
}
It will inject (on place where IService is needed) a BasicService for some basic user and ExtraService for VIP user.
For more information about various ways of conditional binding see Ninject - Contextual binding.
EDIT
I think you can still use conditional binding. You will only need to propagate the IKernel to place where you want to register components from new dll. For example I have this in my global.asax for dynamically loading dll modules - it runs on app startup.
Loading modules:
private void LoadAssemblies(IKernel kernel) {
foreach (var fileName in Directory.GetFiles(Server.MapPath("~/App_Data"), "*.dll")) {
Assembly loadedAssembly = Assembly.LoadFile(fileName);
try {
var moduleRegistrations = loadedAssembly.GetTypes()
.Where(t => t.IsClass && t.IsAbstract == false && typeof (IMyModuleRegistration).IsAssignableFrom(t));
foreach (var moduleRegType in moduleRegistrations ) {
IMyModuleRegistration moduleReg = (IMyModuleRegistration) Activator.CreateInstance(moduleRegType);
moduleReg.RegisterComponents(kernel);
}
}
catch (ReflectionTypeLoadException exception) {
....
}
}
}
Module definition:
public class MyExtraModule : IMyModuleRegistration
{
public void RegisterComponents(IKernel kernel)
{
kernel.Bind<IService>()
.To<ExtraService>()
.When(x => x.ParentContext
.Kernel.Get<IAuthorizationService>()
.IsVIPUser());
}
}
ExtraService will be used only when dll with MyExtraModule is loaded.
EDIT 2
You can download that dll from somewhere. Load it and then test it if it implements your registration interface. Then call that registration and you are done. The only problem I see is: where to store the reference to IKernel - probably some static property in HttpApplication will be enough. You should also track already loaded dlls.
Or in later versions of Ninject I can suggest extending the NinjectModule and then load it into kernel with kernel.Load(..) method. Look at this Modules and kernel - specially in part Dynamic Module Loading - maybe it is what you are looking for.
Use conditional bindings:
Bind<IMyService>().To<MyService>();
Bind<IMyService>().To<MyServiceForVIPs>().When(ctx => CurrentPrincipalIsVIP());
I assume that you know the core ninject modules. You can load all core ninject modules into the kernel. When the special user arrives you could unload the core module und load the user specific module into the kernel.
A better approach would be to have a special kernel in the plugin area. So actually a kernel per plugin approach wich loads the required core modules and adds the user specific ones if any. But that might have performance impacts!
Related
I am a beginner starting out in laravel 5.2 and I think these concepts below should be explained more straight forward than just reading documentation.
Service Providers
Service Container
Contracts
Facades
I think a good explanation and examples that can really help beginners understand how these 4 concepts fit together in the framework.
Service provider :
The so called service providers are the heartbeat of your Laravel application. They are the central element of the initialization process where all the relevant and required code is loaded by PHP. This includes all the essentials from the framework itself, but also any own and custom code you need to load.
Inversion of Control, or IoC :
Can't be explained easly (i only have few ideas about this im not a pro)
Facades :
The Facade pattern is a software design pattern which is often used in object oriented programming. A facade is, in fact, a class wrapping a complex library to provide a simpler and more readable interface to it. The Facade pattern can also be used to provide a unified and well-designed API to a group of complex and poorly designed APIs.
A Laravel facade is a class which provides a static-like interface to services inside the container. These facades, according to the documentation, serve as a proxy for accessing the underlying implementation of the container’s services.
MORE
Contracts :
LARACASTS FREE VIDEO
I know this is not enough! what you are asking is complicated stuff a single answer can't be enough
Ok, so first I agree with the others that laracasts is an amazing resource, that will really go into greater detail and break things down very simply.
That being said, the brief overview is as follows:
Service Container (IoC container) is a laravel core process that allows you to load objects with their dependencies gracefully. For example, If I have a controller method like this:
public function update(Request $request, $id)
{
...
}
IoC container is smart enough to resolve the Request and load up all the dependencies associated with the Request class to make sure it gets instantiated properly.
It also allows you to instantiate classes without having to fully pass along all the dependencies as follows:
class ProductRepo(Product $product)
{
public function get($id)
{
...
}
}
I can reference this class without loading it with dependency injection as follows: (make sure to pass in full namespace)
app('App\ProductRepo')->get($id);
This allows me to not have to pass in a Product Object, Laravel is smart enough to resolve the Product object because the IoC container is doing the magic behind the scenes.
Service Providers are a place for you to lace in custom behavior when booting up or instantiating a class. For example, Laravel by default uses a class called the EventServiceProvider. This class's job is to configure the Event system in Laravel to make sure to include all the custom event listeners you create. So if I wanted to make sure that when the EventDispatcher is being loaded up, it brings in all the necessary dependencies.
Contracts are really simple. They are just an allusion to php object oriented concept of Interfaces. This concept states that there are classes that establish rules. For Example:
interface SearchableInterface
{
public function search($data);
}
class BinarySearch implements SearchableInterface
{
public function search($data)
{
...
}
}
This states that any class that implements the SearchableInterface, must have a function search that accepts one parameter. This creates a 'contract' that any classes that implement the SearchableInterface will have to have this function, or the application will throw an error.
This is great for using interchangeable pieces (siblings) and not having to worry that the class is missing a function you need.
Last but not least is the Facade. I love facades. In a nutshell all this is doing is creating a static representation of a class that was not defined statically. So lets say I have a class that will get a document from S3.
class S3
{
public function get($file)
{
...
}
}
Without a facade you would first have to instantiate and then call get on the class in order to get something from S3.
$s3 = new S3;
$s3->get('myAwesomeFile');
Laravel allows you to easily register Facades so that you can just use this statically for readability and convenience.
S3::get('MyAwesomeFile');
All of this has been an over-simplification of each concept, but goes into some detail about some of the basics of each concept. Hope this helps!
I am using MVVM light and figured out since that the ViewModelLocator can be used to grab any view model and thus I can use it to grab values.
I been doing something like this
public class ViewModel1
{
public ViewModel1()
{
var vm2 = new ViewModelLocator().ViewModel2;
string name = vm2.Name;
}
}
This way if I need to go between views I can easily get other values. I am not sure if this would be best practice though(it seems so convenient makes me wonder if it is bad practice lol) as I know there is some messenger class thing and not sue if that is the way I should be doing it.
Edit
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<ViewModel1>();
SimpleIoc.Default.Register<ViewModel2>();
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic",
Justification = "This non-static member is needed for data binding purposes.")]
public ViewModel1 ViewModel1
{
get
{
return ServiceLocator.Current.GetInstance<ViewModel1 >();
}
}
Edit
Here is a scenario that I am trying to solve.
I have a view that you add price and store name to. When you click on the textbox for store name you are transferred to another view. This view has a textbox that you type the store you are looking for, as you type a select list get populated with all the possible matches and information about that store.
The user then chooses the store they want. They are transferred back to the view where they "add the price", now the store name is filled in also.
If they hit "add" button it takes the price, the store name, and the barcode(this came from the view BEFORE "add price view") and sends to a server.
So as you can see I need data from different views.
I'm trying to understand what your scenario is. In the MVVMlight forum, you added the following context to this question:
"I have some data that needs to be passed to multiple screens and possibly back again."
For passing data between VMs, I would also - as Matt above - use the Messenger class of MVVMLight as long as it is "fire and forget". But it is the "possibly back again" comment that sounds tricky.
I can imagine some scenarios where this can be needed. Eg. a wizard interface. In such a case I would model the data that the wizard is responsible for collecting and then bind all Views to the same VM, representing that model object.
But that's just one case.
So maybe if you could provide a little more context, I would be happy to try and help.
Yes, you can do this, in as much as the code will work but there is a big potential issue you may run into in the future.
One of the strong arguments for using the MVVM pattern is that it makes it easier to write code that can be easily tested.
With you're above code you can't test ViewModel1 without also having ViewModelLocator and ViewModel2. May be that's not too much of a bad thing in and of itself but you've set a precedent that this type of strong coupling of classes is acceptable. What happens, in the future, when you
From a testing perspective you would probably benefit from being able to inject your dependencies. This means passing, to the constructor--typically, the external objects of information you need.
This could mean you have a constructor like this:
public ViewModel1(string vm2Name)
{
string name = vm2Name;
}
that you call like this:
var vm1 = new ViewModel1(ViewModelLocator.ViewModel2.name);
There are few other issues you may want to consider also.
You're also creating a new ViewModelLocator to access one of it's properties. You probably already have an instance of the locator defined at the application level. You're creating more work for yourself (and the processor) if you're newing up additional, unnecessary instances.
Do you really need a complete instance of ViewModel2 if all you need is the name? Avoid creating and passing more than you need to.
Update
If you capture the store in the first view/vm then why not pass that (ID &/or Name) to the second VM from the second view? The second VM can then send that to the server with the data captured in the second view.
Another approach may be to just use one viewmodel for both views. This may make your whole problem go away.
If you have properties in 1 view or view model that need to be accessed by a second (or additional) views or view models, I'd recommend creating a new class to store these shared properties and then injecting this class into each view model (or accessing it via the locator). See my answer here... Two views - one ViewModel
Here is some sample code still using the SimpleIoc
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<IMyClass, MyClass>();
}
public IMyClass MyClassInstance
{
get{ return ServiceLocator.Current.GetInstance<IMyClass>();}
}
Here is a review of SimpleIOC - how to use MVVMLight SimpleIoc?
However, as I mentioned in my comments, I changed to use the Autofac container so that my supporting/shared classes could be injected into multiple view models. This way I did not need to instantiate the Locator to access the shared class. I believe this is a cleaner solution.
This is how I registered MyClass and ViewModels with the Autofac container-
var builder = new ContainerBuilder();
var myClass = new MyClass();
builder.RegisterInstance(myClass);
builder.RegisterType<ViewModel1>();
builder.RegisterType<ViewModel2>();
_container = builder.Build();
ServiceLocator.SetLocatorProvider(() => new AutofacServiceLocator(_container));
Then each ViewModel (ViewModel1, ViewModel2) that require an instance of MyClass just add that as a constructor parameter as I linked initially.
MyClass will implement PropertyChanged as necessary for its properties.
Ok, my shot at an answer for your original question first is: Yes, I think it is bad to access one VM from another VM, at least in the way it is done in the code example of this question. For the same reasons that Matt is getting at - maintainability and testability. By "newing up" another ViewModelLocator in this way you hardcode a dependency into your view model.
So one way to avoid that is to consider Dependency Injection. This will make your dependencies explicit while keeping things testable. Another option is to use the Messenger class of MVVMLight that you also mention.
In order to write maintainable and testable code in the context of MVVM, ViewModels should be as loosely coupled as possible. This is where the Messenger of MVVMLight can help. Here's a quote from Laurent on what Messenger class was intended for:
I use it where decoupled communication must take place. Typically I use it between VM and view, and between VM and VM. Strictly speaking you can use it in multiple places, but I always recommend people to be careful with it. It is a powerful tool, but because of the very loose coupling, it is easy to lose the overview on what you are doing. Use it where it makes sense, but don't replace all your events and commands with messages.
So, to answer the more specific scenario you mention, where one view pops up another "store selection" view and the latter must set the current store when returning back to the first view, this is one way to do it (the "Messenger way"):
1) On the first view, use EventToCommand from MVVMLight on the TextBox in the first view to bind the desired event (eg. GotFocus) to a command exposed by the view model. Could be eg. named OpenStoreSelectorCommand.
2) The OpenStoreSelectorCommand uses the Messenger to send a message, requesting that the Store Selector dialog should be opened. The StoreSelectorView (the pop-up view) subscribes to this message (registers with the Messenger for that type of message) and opens the dialog.
3) When the view closes with a new store selected, it uses the Messenger once again to publish a message that the current store has changed. The main view model subscribes to this message and can take whatever action it needs when it receives the message. Eg. update a CurrentStore property, which is bound to a field on the main view.
You may argue that this is a lot of messaging back and forth, but it keeps the view models and views decoupled and does not require a lot code.
That's one approach. That may be "old style" as Matt is hinting, but it will work, and is better than creating hard dependencies.
A service-based approach:
For a more service-based approach take a look at this recent MSDN Magazine article, written by the inventor of MVVMLight. It gives code examples of both approaches: The Messenger approach and a DialogService-based approach. It does not, however, go into details on how you get values back from a dialog window.
That issue is tackled, without relying on the Messenger, in this article. Note the IModalDialogService interface:
public interface IModalDialogService
{
void ShowDialog<TViewModel>(IModalWindow view, TViewModel viewModel, Action<TViewModel> onDialogClose);
void ShowDialog<TDialogViewModel>(IModalWindow view, TDialogViewModel viewModel);
}
The first overload has an Action delegate parameter that is attached as the event handler for the Close event of the dialog. The parameter TViewModel for the delegate is set as the DataContext of the dialog window. The end result is that the view model that caused the dialog to be shown initially, can access the view model of the (updated) dialog when the dialog closes.
I hope that helps you further!
I have a menu which I need to create dynamically (some blog pages are added from a database). ZF2 Dynamic Menu with Zend\Navigation\Navigation addresses how to do this for an individual controller/action.
But how should this be done for all requests, at the moment of initialising the module?
I need at least the routeMatch object (to get the language parameter) and I have seen the below to get that:
public function onBootstrap(EventInterface $e)
{
$app = $e->getApplication();
$em = $app->getEventManager();
$em->attach(MvcEvent::EVENT_ROUTE, function($e) {
$routeMatch = $e->getRouteMatch();
});
}
But in the docs it says:
"the onBootstrap() method is called for every module implementing this feature, on every page request, and should only be used for performing lightweight tasks such as registering event listeners."
What would be the best place and way to initialise dynamic navigation (or other more complicated logic) in Zend Framework 2?
The correct place is indeed bootstrap to do this sort of things. Bear in mind the code at bootstrap is run at every request, so make it as lightweight as possible. If you want to inject navigation, try to cache the navigation structure from your database and inject the version from cache.
This behaviour is something I did in ensemble. It fetches data from the database to build routes dynamically and based on the routes, the navigation structure is build. The routes and navigation are injected in respectively the router and navigation container, so at dispatch of the application is seems there is nothing different from a "normal" request with routes configured in the module.config.php.
For some examples you should check out the kernel, currently only availble with a Doctrine adapter (Zend\Db coming soon). It registers listeners to hook up early, it parses the database results into a route and navigation structure and those can be cached to increase performance.
If you need more specific information, please update your question to ask more about what you miss in the bigger picture.
Slogging through MVC+EF and trying to focus on doing things the right way. Right now I'm looking to add a dropdown to a form but I'd like to avoid hitting the database every time the page loads so I'd like to store the data in the app level. I figure creating an application level variable isn't the best approach. I've read about using the cache and static utility functions but surprisingly, nothing has sounded terribly definitive. (Static classes bad for unit testing, caching bad
So I have two scenarios that I'm curious about, I'm not sure if the approach would differ between the two.
1) A basic lookup, let's say the fifty states. Small, defined, will never change. Load at application startup. (Not looking for a hard coded solution but retrieval from the database.)
2) A lookup that will very rarely change and only via an admin-like screen. Let's say, cities/stores where your product is being sold. So data would be stored
in the model but would be relatively static unless someone made changes via the application. So not looking to hit the database every time I need to populate a dropdown/listbox.
Seems like basic stuff but it's basically the same as this topic that was never answered:
Is it good to use a static EF object context in an MVC application for better perf?
Any help is appreciated.
I will address you question in a few parts. First off, is it inherently bad to use static variables or caching patterns in MVC. The answer is simply no. As long as your architecture supports them it is OK. Just put your cache in the right place and design for testability as I will explain later.
The second part is what is the "right" way to have this type of persisted data stored so you don't have to make round trips to the DB to populate common UI items. For this, I don't recommend storing EF objects. I would create POCO objects (View models or similar) that you cache. So in the example of your 50 states you might have something like this:
public class State
{
public string Abbreviation { get; set; }
public string Name { get; set; }
}
Then you would do something like this to create your cached list:
List<State> states = Context.StateData.Select(s => new State { Abbreviation = s.Abbreviation, Name = s.Name}).ToList();
Finally, whatever your caching solution is, it should implement an interface so you can mock that caching method for testing.
To do this without running into circular references or using reflection, you will need at least 3 assemblies:
Your MVC application
A class library to define your POCO objects and interfaces
A class library do perform your data access and caching (this can obviously be split into 2 libraries if that makes it easier to maintain and/or test)
That way you could have something like this in your MVC code:
ICache myCache = CacheFactory.CreateCache();
List<State> states = myCache.ListStates();
// populate your view model with states
Where ICache and State are in one library and your actual implementation of ICache is in another.
This is what I do for my standard architecture: splitting POCO objects and interfacees which are data access agnostic into a separate library from data access which is the separate from my MVC app.
Look into using a Dependency Injection tool such as unity, ninject, structuremap, etc. These will allow for the application level control you are looking for by implementing a kernel which holds on to objects in a very similar way to what you seem to be describing.
Using Castle.Windsor in ASP.NET MVC (3.0) is there any way I can appropriately handle if one of my dependencies resolves null? For instance, say I have a IMembershipService.
class ServiceInstaller
{
// ...
void Install( // .. )
{
container.Register(
Component
.For<IMembershipService>()
.ImplementedBy<MembershipService>()
.LifeStyle.PerWebRequest
);
}
}
Okay, this works great. Now, perhaps not all of my site requires a user to be logged in. Let's assume that maybe my web host's database server crashes for a few hours. In that event, things that looked into the database, or tried to call on my ISession might return null.
What can I do in this case? I can write if(membershipService == null) a hundred times over, but that seems pretty dumb. Is there a built-in solution to say "Hey, if we have an error, do this..?"
I think that the service should never be null. If the database is down, the service should be returned nevertheless, but its methods should throw an exception, return null or some default value, depending on the semantic of the service.
Ciel, i had this problem just recently and found your question while looking for the answer.
Basically you should be using a typed factory to resolve your components at runtime in your wrapping component. The factory should return a default object if there is no match regarding the component you're looking for, default object that would implement whatever behavior is needed.
In the case of your IMembershipService, implement a NotCheckingMembershipService class inheriting the interface and doing nothing and make it the default for the components that won't need it. More specific membership services can be linked to specific controllers.
To do so you must create a generic "catch-all" implementation
public class NotCheckingMembershipService<T>: IMembershipService<T> where T: Controller
{
}
And register it as the default component for an open IMembershipService
_container.Register(
Component.For(typeof(IMembershipService<>))
.ImplementedBy(typeof(NotCheckingMembershipService<>))
.IsDefault());
Then simply register your custom membership services where needed. Resolution won't fail and you will always be able to call the interface.