Modello vincolante un oggetto dal repository diverse chiavi
-
25-09-2019 - |
Domanda
Si supponga che il seguente percorso:
{region}/{storehouse}/{controller}/{action}
Questi due parametri region
e storehouse
complessivamente identificare una singola entità - un Storehouse
. Pertanto, un gruppo di controllori vengono chiamati nel contesto di qualche magazzino.
E mi piacerebbe scrivere azioni come questa:
public ActionResult SomeAction(Storehouse storehouse, ...)
Qui posso leggere i tuoi pensieri: "Modello di scrittura personalizzati legante, l'uomo". Lo voglio. Tuttavia, la questione è
Come evitare le stringhe di magia all'interno modello personalizzato legante?
Qui è il mio codice corrente:
public class StorehouseModelBinder : IModelBinder
{
readonly IStorehouseRepository repository;
public StorehouseModelBinder(IStorehouseRepository repository)
{
this.repository = repository;
}
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var region = bindingContext.ValueProvider.GetValue("region").AttemptedValue;
var storehouse = bindingContext.ValueProvider.GetValue("storehouse").AttemptedValue;
return repository.GetByKey(region, storehouse);
}
}
Se ci fosse un singolo tasto, bindingContext.ModelName
potrebbe essere utilizzato ...
Probabilmente, c'è un altro modo di fornire tutte le azioni con un oggetto Storehouse
, cioè dichiarando come una proprietà del controller e popolamento nel Controller.Initialize
.
Soluzione
Ho finito con un altro approccio. Modello vincolante non è un meccanismo appropriato per il mio scopo. Azione Filter è la strada da percorrere!
I nomi non sono gli stessi nella questione, ma Site trattare come Storehouse.
public class ProvideCurrentSiteFilter: IActionFilter
{
readonly ISiteContext siteContext;
public ProvideCurrentSiteFilter(ISiteContext siteContext)
{
this.siteContext = siteContext;
}
void IActionFilter.OnActionExecuted(ActionExecutedContext filterContext)
{
}
void IActionFilter.OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.ActionParameters["currentSite"] = siteContext.CurrentSite;
}
}
ISiteContext
realizzazione analizza HttpContext.Current
e tira un oggetto dal sito Repository. Utilizzando HttpContext.Current
non è troppo elegante, d'accordo. Tuttavia, tutto passa attraverso CIO, quindi verificabilità non soffre.
C'è un attributo di filtro azione denominato ProvideCurrentSiteAttribute
che utilizza ProvideCurrentSiteFilter
. Quindi, il mio metodo d'azione che assomiglia a:
[ProvideCurrentSite]
public ActionResult Menu(Site currentSite)
{
}