What are exactly Laravel Contracts? - laravel

I'm new to Laravel & I wanted to know something about it's feature that calls Contracts.
(If my question not in place, let me know why, and don't just downvote it).
So from what I red in Laravel Documentation and say on Laracasts videos, I understood that contracts they are only interfaces for class implementation.
So what it's good for? That if I or someone else will implement those interfaces will all need to go by the interface and then I dont need to change my code at all?
Is that the reason why Laravel uses it's implementation as a contracts ?
Also I wanted to know, to achive the implementation I must bind the implementation to a contract?

Yes, I think your understanding is mostly correct. I will try to explain with an example. Let's say you have a PackageDeliveryServiceContract that has some methods like trackPackage, getShippingCost.
You create a FedexDeliveryService to adhere to the contract and implement those methods.
In your controller, you can just inject PackageDeliveryServiceContract and start using it right away. (are you familiar with laravel's dependency injection?).
Let's say later you decide you no longer want to ship with Fedex and use UPS instead. Then you can create UPSDeliveryService that also adheres to that contract.
Now, all you need to do is change your binding from FedexDeliveryService to UPSDeliveryService and you don't need to make any changes to your controller code.
Typically you will create the binding between contract and implementation inside a service provider such as app/Providers/AppServiceProvider.php

Related

How can i set the api version on a generic controller when loading a plugin?

I have some plugin's which are basically input and output type definitions. I have a generic controller which i can add to the mvc pipeline. All works fine.
but I'm having trouble setting the api version on this generic controller. I know you can set this based upon an attribute on top of the controller class. But since you can't have this dynamic (attribute) don't allow it, i have no way to set the version for each instance of the generic controller.
Currently i just compile the controller for each instance on runtime and register i using the roslyn compiler.
is there a way to set the api-version somewhere in the pipeline of registering controllers in the mvc pipeline and endup with different api versions endpoints.
This can be achieved by using the Conventions API. It was designed to support this exact type of scenario:
https://github.com/microsoft/aspnet-api-versioning/wiki/API-Version-Conventions
This will only work on closed-generics, but it shouldn't be too much work to make that happen. Here's a couple of basic examples:
// typed, closed generic
options.Conventions.Controller<GenericController<PlugIn1>>().HasApiVersion(1,0);
// untyped, closed generic
var controllerType = typeof(GenericController<>).MakeGenericType(new []{typeof(PlugIn1)});
options.Conventions.Controller(controllerType).HasApiVersion(1,0);
You can also author your own custom conventions a la IControllerConvention. This approach could be used to version all controllers that inherit from GenericController<>. Then you just need to add it to the conventions like this:
options.Conventions.Add(new PlugInControllerConvention());
Hopefully that's enough to get you started. Feel free to ask more questions.

Laravel docs do a contract vs facade but fail to explain what it is really about

from the official docs
https://laravel.com/docs/5.4/facades
this seems easy to test (the cache class)
public function testBasicExample()
{
Cache::shouldReceive('get')
->with('key')
->andReturn('value');
$this->visit('/cache')
->see('value');
}
as well in the documentation of facades it is written:
When building a third-party package that interacts with Laravel, it's
better to inject Laravel contracts instead of using facades. Since
packages are built outside of Laravel itself, you will not have access
to Laravel's facade testing helpers.
I really don't see how this is true. The package very well will access functions of laravel, so I don't see how it should not work with testing?
now in contracts https://laravel.com/docs/5.4/contracts they go on a little philosophical discussion what to use, facades or contracts. Isn't it better to use them together? Because contracts are nothing else than an interface. Now the idea of an interface is not new at all. I don't really get, what is the point about first of all comparing facades and contracts when:
facades are basically a extended class of laravel adding testing possibilities. They hide the implementation though and make it harder to read what functions are available on the class. E.g. you always first have to figure out what implementation is used of the facade, to see what methods there are.
contracts on the other hand are nothing else than interfaces. Basically the laravel people telling us "use interfaces". I agree, interfaces are great. But I don't see in what way this relates to facades. They are not related. They are not interchangeable neither.
So what is this all about?
why say "use contracts OR facades" they are not related, and should be used together imho.
An example is the Mail facade:
/**
* #see \Illuminate\Mail\Mailer
*/
class Mail extends Facade{...
so accessing Mail:: will return an instance of \Illuminate\Mail\Mailer
lets look at \Illuminate\Mail\Mailer
class Mailer implements MailerContract, MailQueueContract
{
nothing else than a class implementing a contract aka interface.
What exactly are they trying to tell us?
third-party package
is key term here to consider. Not every package is used with Laravel only.
The package very well will access functions of laravel
Is that true if I use CodeIgniter? Nope.
Now if you build a package specifically for Laravel, then by all means, use facades all day.
The whole point of this is to not couple yourself tightly with a single framework.

How is Autofac's IComponentContext being resolved in a BotBuilder sample?

A pretty specific query I know but one that hopefully applies more generally to the use of Autofac across the BotFramework SDK.
In the 'ContosoFlowers' sample, the DialogFactory class receives its 'scope' member, an Autofac IComponentContext, as its one constructor parameter.
However, I'm mystified as to where this comes from. I have an irrational hatred of DI anyway, but I still can't find some bootstrapper/service locator/module etc. that somehow links this to a concrete implementation. No obvious module. Is it baked in somewhere in the BotFramework code?
Also, can I ask what the purpose is of having all this DialogFactory.ContosoFlowersDialogFactory.Create() layer is? Say for example, when calling this.dialogFactory.Create<FlowerCategoriesDialog>()? This I assume is to avoid having to 'new' the dialog, and because the DI scope isn't available to the calling dialog? In that case, why have this factory injected into the RootDialog and not the IComponentContext scope itself?
Apologies if noob questions (very likely). Also please advise if there's a better place/forum for specific BotFramework samples code queries. Thanks!
Good questions! Let me try to address them:
IComponentContext. There is no registration/bootstrap of that interface. They are automatically provided by Autofac (see here).
ContosoFlowersDialogFactory. Your assumption is correct, the idea of having a dialog factory is to avoid having to 'new' dialogs manually, as that adds limitations around unit testing for example. Certainly, the approach you are suggesting is valid; and nothing prevents you to use the IComponentContext in the dialogs (please not that not only the RootDialog is using the factory, but also the other dialogs such as the SettingsDialog or the SavedAddressDialog). The reasons of having that layer could be subjective, so I would just provide you my point of view here. IMO, having these layers contribute to have a cleaner code and to avoid having DI's specific components across the application. In this scenario, the DialogFactory is the responsible of dealing with the DI layer, allowing you; to change the DI mechanism if you want; without having to update all the other components; or even in the case of a breaking change on Autofac; you will have just to deal with it in the factory. If I have to choose, I would prefer not having direct Autofac.* dependencies in my dialogs.

Hidden Laravel Methods (5.1)

First, I have IDE helper, and the php storm plugin. I tried the Gist pre made too. There are some similar questions, but no one seems to get answers. I'll probably poke laracasts and ide helper bug list if I don't get anything here.
So I'm following along to some of the into laracasts, and the guy keeps using methods that are not defined as far as I can tell. Situation:
I created a eloquent model called Article. It extends
Illuminate\Database\Eloquent\Model
So now I have App\Article and I can call any of the methods available to model. For example:
$article = \App\Article::all();
PHPStorm is happy. He keeps pulling stuff like ::find() or ::findOrFail()
It's in the docs
I just don't under stand how that works, I don't see the methods defined in model. If this is what ide helper is supposed to fix, then I'm not certain it's working correctly. I can RTFM, I'm pretty sure I followed the directions to a tee.
Ya know, I just found it. I see this question out and about, so I'll answer it here.
https://github.com/barryvdh/laravel-ide-helper/issues/248#issuecomment-131503475
Fixed find or fail for me. find is still MIA. I'm surprised laravel doesn't support their code base in the forms of plugins or dedicated IDE's bit more. It's all just people out there creating a community and moving the world forward so I can't complain too much.
It works because Model implements __callStatic() which dispatches it to itself on a new instance: __callStatic() implementation on Model
It creates a new instance (new static) of the model in question and dispatches the statically called method on the instance.
Effectively, Model::foo($bar) is the same as (new Model)->foo($bar).

What is the best way to implement the versioning for ASP.NET WebAPIs?

What is the best approach to version WebAPIs?
I am building an API from scratch and I would like to ensure that it will version gracefully in the future. I am envisioning something like mysite.com/api/v2/...
One approach I see is to create a separate project (web app) for each version of API. But perhaps there are better ways to do it?
Thank you for your ideas.
Including version number in the URL is the standard approach as I explained in this post (I do not repeat the content): Implementing versioning a RESTful API with WCF or ASP.Net Web Api
You do not need to create a completely new project although you can. The problem that you will be facing with a single project is that there will be collision of names:
/api/v1.0/Car/123
and
/api/v2.0/Car/123
both will point to CarController while you can have only one of those. The solution would be to implement your own IHttpControllerSelector and register with the DependencyResolver. This implementation will look at the version number and perhaps find the type based on the namespace.
UPDATE
I do not intend to start a REST controversy here. But as #DarrelMiller points out, here is an older discussion on the same subject discouraging my suggested approach:
How to version REST URIs
I personally think URL versioning is the way to go.
You will need to create your own implementation of IHttpControllerSelector. The best way is to base this implementation on Microsoft's IHttpControllerSelector. Then you can decide in your IHttpControllerSelectorif you want to version by URL or by content-type.
The most basic implementation directly implements IHttpControllerSelector and just implements the SelectController method but performance reasons it is better to implement some caching around it.
For finding the Controller you simple the IHttpControllerTypeResolver instance you can get using HttpConfiguration.Services.
I've used something like this: http://damsteen.nl/blog/implementing-versioning-in-asp.net-web-api. Also put some code on Github: https://github.com/Sebazzz/SDammann.WebApi.Versioning.

Resources