I am studying the framework entities and need to add a method in the #view.
This is My code:
#Views({
#View(
name="CreatClient",
title="Cliente",
members="#Codigo;#nome;#Telefone;#Endereco",
rows=10)
});
You need add the method name after of endereco in members...
;methodname()
And make the method in the class
Related
Is there any possible way to lazy load a custom attribute on a Laravel model without loading it every time by using the appends property? I am looking for something akin to way that you can lazy load Eloquent relationships.
For instance, given this accessor method on a model:
public function getFooAttribute(){
return 'bar';
}
I would love to be able to do something like this:
$model = MyModel::all();
$model->loadAttribute('foo');
This question is not the same thing as Add a custom attribute to a Laravel / Eloquent model on load? because that wants to load a custom attribute on every model load - I am looking to lazy load the attribute only when specified.
I suppose I could assign a property to the model instance with the same name as the custom attribute, but this has the performance downside of calling the accessor method twice, might have unintended side effects if that accessor affects class properties, and just feels dirty.
$model = MyModel::all();
$model->foo = $model->foo;
Does anyone have a better way of handling this?
Is this for serialization? You could use the append() method on the Model instance:
$model = MyModel::all();
$model->append('foo');
The append method can also take an array as a parameter.
Something like this should work...
public function loadAttribute($name) {
$method = sprintf('get%sAttribute', ucwords($name));
$this->attributes[$name] = $this->$method();
}
I'm building an MVC3 application using the Entity Framework. In the application my controllers talk to a service layer. One of the controllers is a TournamentController which uses the TournamentService. This service has some standard methods such as CreateTournament, UpdateTournament etc.
When I want to insert a new tournament I want the view to have a dropdownlist of possible sports for which the tournament can be organised. So in the TournamentController's Create method I fill the ViewBag.Sports with a list of possible sports. Now to obtain this list of sports I use _tournamentService.GetAllSports(). In this GetAllSports() method of the TournamentService I want to create an instance of the SportService so I can 'forward' the question to the right service.
All services use dependency injection in the constructor to inject their own repository, like so:
private ITournamentRepository _repo;
public TournamentService(ITournamentRepository repo) {
_repo = repo;
}
My GetAllSports() method in the TournamentService looks like this:
public IEnumerable<Sport> GetAllSports() {
ISportService sportService = new SportService();
return sportService.GetSports();
}
The problem is that by calling the new SportService() it expects me to hand it an ISportRepository like in the TournamentService, where ninject creates the TournamentRepository. Now I could do the following:
public IEnumerable<Sport> GetAllSports() {
ISportService sportService = new SportService(new SportRepository());
return sportService.GetSports();
}
But the problem with that is that each repository expects an IContext, which is normally handled by ninject as well. Furthermore, I don't want two separate contexts to be instantiated.
A possible solution I found myself is to do this:
private ITournamentRepository _repo;
private ISportService _sportService;
public TournamentService(ITournamentRepository repo, ISportService sportService) {
_repo = repo;
_sportService = sportService
}
But there's only one method in my TournamentService class that would actually use the _sportService so I figure this is a bit overkill to make it a class attribute.
Keep it simple, inject ISportService to your controller and call sportService.GetSports() directly from the controller!
Your last solution valid. Inject the necessary service as part of the constructor.
And if you're worried about multiple contexts, don't let two separate contexts be created then.
In your Ninject binding:
Bind<ITournamentRepository>().To<TournamentRepository>().InRequestScope();
See https://github.com/ninject/Ninject.Web.Common/wiki/InRequestScope
The last piece is the important part. It will only create one instance of TournamentRepository for the current request. Any other requesters of TournamentRepository will get this instance.
If you're already doing this, you're set, otherwise, just add InRequestScope and you're done. (keeping in mind you'll need a reference to Ninject.Web.Common)
Hope that helps.
EDIT:
Remo is correct, I wouldn't call this from a service either. Just call for your lookup data from the controller and populate your view model. The InRequestScope advice still holds.
I'm currently working on an MVC 3 project using Ninject as my DI, the business objects are stored in a separate assembly. I'm running into an issue with the controller parameters, when posting back for CRUD operations I'm getting the error "Cannot create an instance of an interface". I am aware that you can't create an instance of an interface, but it seems like the only way I can get around this is to use a custom model binder and pass the FormCollection through. This seems really messy and I want to keep as much type specific code out of the project as I can - hence interfaces everywhere and Ninject to DI the concretes. Not only does custom model binding seem messy - won't I also lose my DataAnnotations?
Some code to describe what I have:
public ActionResult Create()
{
// I'm thinking of using a factory pattern for this part
var objectToCreate = new ConcereteType();
return (objectToEdit);
}
[HttpPost]
public ActionResult Create(IRecord record)
{
// check model and pass to repository
if (ModelState.IsValue)
{
_repository.Create(record);
return View();
}
return View(record);
}
Has anyone run into this before? How did you get over it?
Thanks!
but it seems like the only way I can get around this is to use a custom model binder
A custom model binder is the correct way to go. And by the way you should use view models as action arguments, not domain models or interfaces.
Not only does custom model binding seem messy - won't I also lose my DataAnnotations?
I don't know why you think that a custom model binder would make things messy. For me it's a great way to separate mapping logic into a reusable class. And, no you will not lose DataAnnotations. They will work perfectly fine on the concrete instance that the custom model binder would return.
Data passed to controllers action are simply holders for values. There shouldn't be any logic in them so there is nothing to decouple from. You can use concrete types (e.g Record) instead of interface (IRecord)
I made the same simple mistake. Ninject injects parameters into your constructor, but you added parameters to the Index Controller action.
It should look like this:
public class HomeController : Controller
{
private IRecord _record;
public HomeController(IRecord record)
{
_record = record;
}
public ActionResult Index()
{
ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application. " +
_record .HelloWorld();
return View();
}
}
Make sense?
Is there a way for the controller to pass a tuple as a model to the View?
Something like this:
return View(Tuple<LandingPage, Models.FilterModel>(landingPage, filter));
Thank you
Yes, you just need to instantiate the Tuple:
return View(new Tuple<LandingPage, Models.FilterModel>(landingPage, filter));
Although you're probably better off creating a composite view model type which contains properties for the landing page and the filter model.
I am sure there has to be an easy way to do this, but I just cant seem to get my head around it.
I am using the MVCContrib Grid control to display a number of grids in a 3 tier application I am working on (ASP.NET MVC3 PL -> BLL -> DAL). I also am using Ninject to automatically inject all my dependencies.
The problem I am having is that I am using a grid model to display grids in my Views like this:
#Html.Grid(Model).WithModel(new UserGridModel(Html)).Attributes(id => tableName)
and have the corresponding grid model defined:
public class UserGridModel : GridModel<User> {
public UserGridModel(HtmlHelper html)
{
Dictionary<int, string> userStatuses = /*TODO: GET ALL USER STATUSES*/;
Column.For(user => user.ID);
Column.For(user => html.ActionLink(user.Email, "Edit", new {id = user.ID})).Named(DtoResources.UserDto_Email);
Column.For(user => user.FirstName);
Column.For(user => user.LastName);
Column.For(user => userStatuses[user.StatusID]);
}
}
Now I need to inject a service into this model so it can pull in all of the applicable statuses from the service (BLL) level. Currently just to make sure this would work, I exposed the IKernel in the Bootstrapping code and just IKernel.Get() but I don't think that is the cleanest way to get it. I would use constructor injection, but if I put the IUserStatusService as a parameter in the constructor, I can't figure out how I would get Ninject to inject the correct parameter when I call new UserGridModel(Html) in the view without explicitly using the IKernel there.
I am either missing something or wiring this up all wrong. Either way I'm stuck ... any help? What is the proper way to get an instance of my service through Ninject
In my opinion the cleanest solution to your problem is to change your controller so that it creates a model that already contains the user status as string so that no convertions is required in the view. I would do as littel as possible in the view and grid model.
Another possibility is to property inject the service to your view an pass it to the grid model. But as I mentioned this way you are introducing logic to your view.