Question

I have an Ability class which looks like this

L1.

public class Ability
{
    public int Id { get; set; }
    public string Name {get; set;}
}

There are also many more enumlike classes that have Id and Name. So im writing Generic class to have less work later with them.

L2.

public class EnumRepository<TEnum>where TEnum : class
{ ... }

One method od said class looks like this:

L3.

public IEnumerable<SelectListItem> ToSelectListItem(
    Expression<Func<TEnum, IEnumerable<Tuple<string, int>>>> text = null)
{
    IQueryable<TEnum> query = dbSet;
    var ret = new List<SelectListItem>();

    if (text != null)
    {
        var res = query.SelectMany(text);

        foreach (var tuple in res)
        {
            ret.Add(new SelectListItem()
                {
                    Text = tuple.Item1,
                    Value = tuple.Item2.ToString()
                });
        }
    }

    return ret;
}

But I wore sth that I dont know how to use...

L4.

ret.Abilities = _unitOfWork.AbilityRepository
                    .ToSelectListItem( !what goes here?! )

Here are my questions:

  1. What to put into metod argument in L4. to make it work?
  2. Is there better way to do this?
  3. Is it worth to do it?

In my old aproach I wrote ToSelectListItems in each class of this type. And using it was simple, like this ret.Abilities = Ability.ToSelectListItems() <- static method. But I had to do write this code in every class = hard to maintain and dumb way of doing things.

Was it helpful?

Solution

Assuming I understand your problem correctly, here goes:

What to put into metod argument in L4. to make it work?

Assuming for some reason you want to go ahead with your setup (please see below), you'd have to do something along those lines:

ret.Abilities =
   _unitOfWork.AbilityRepository
              .ToSelectListItem(item => new[] { new Tuple<String, int> (
                                                      (YourAbilityClass)item.Id,
                                                      (YourAbilityClass)item.Name)) };

which is slightly counterproductive, as you'd need to maintain part of your repository logic in every call.

Is there better way to do this?

Define better :). The way I would approach is as follows:

1) Define a new base class for all your entities, something like

public class BaseClass
{
   public int Id { get; set; }
   public String Name { get; set; }
}

and have all your relevant entities inherit from it:

public class Ability : BaseClass
{
}

(alternatively use a common interface - that depends on your design, so I can't make an informed suggestion here)

2) Then constraint your repositories to use BaseClass, like so:

public class EnumRepository<TEnum>where TEnum : BaseClass { ... }

3) Finally you can have

public IEnumerable<SelectListItem> ToSelectListItem()
{
    return dbSet.Select(bc => new SelectListItem()
                                   {
                                     Text = bc.Name,
                                     Value = bc.Id.ToString()
                                   })
                .ToArray();
}

and call it like so:

ret.Abilities = _unitOfWork.AbilityRepository.ToSelectListItem();

Is it worth to do it?

It's always hard to make fool-proof comments against someone else's design, if we're only shown a very small percent of it. Make your own decision - I do believe my suggestion might be a bit simpler in the long run, assuming it fits your needs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top