Returning SelectListItem from DAL or Domain or equivalent
If my requirement was to return data for a DropDownlist in a webform, a winform, a wpf form etc from a separate dll (DAL, Domain etc). What would you return?
I could use:
SelectListItem[]
Ilist<SelectListItem>
IEnumerable<SelectListItem>
and the others of a s开发者_StackOverflow社区imilar nature but I dont like the way 'SelectListItem' is tied to the System.Web.Mvc namespace. Maybe its just me but it just seems a little specific. My webform may not even be using MVC although it would still work?
I think you have sort of answered your own question in that it is inappropriate to return a SelectList from an assembly that may be consumed by applications that are not asp.net MVC. This would even lead to a WPF application have to reference System.Web.Mvc.
A more appropriate architecture would be to return an IEnumerable of some type that you will then convert to the appropriate list item type for the current application type. This conversion could occur in some sort of adapter layer or via extension methods if that is more helpful to you.
I have come across the same problem and my solution was to create a tiny class in the services layer and map the data to SelectListItem
s in the view. Example code:
1) Surrogate class in the services layer:
public class SelectListItemBase
{
public String Value { get; set; }
public String Text { get; set; }
}
2) The view model:
public class FetchWordsIntegrationViewModel
{
public IList<SelectListItemBase> WordTypes { get; private set; }
public FetchWordsIntegrationViewModel()
{
WordTypes = new List<SelectListItemBase>();
WordTypes.Add(new SelectListItemBase() { Value = "0", Text = Constants.Ids.SelectionListDefaultText });
WordTypes.Add(new SelectListItemBase() { Value = ((int)FetchedWordType.ProperNoun).ToString(), Text = "Proper noun" });
// other select list items here
}
}
3) Code in the action
public ActionResult Index()
{
var vm = theService.CreateViewModel();
return View(vm);
}
4) Mapping using Automapper (this is not required as SelectListItem
s can easily be generated using LINQ)
Mapper.CreateMap<SelectListItemBase, SelectListItem>();
5) Finally, code from the view
@Html.DropDownListFor(m => m.WordTypes,
(IEnumerable<SelectListItem>)Mapper.Map(
Model.WordTypes,
typeof(IList<SelectListItemBase>),
typeof(IList<SelectListItem>))
)
It is quite convoluted for this simple task, but allows desired decoupling and also allows to easy map other properties, if needed.
精彩评论