Why is everything so protected and internal?
VictorioBerra opened this issue · comments
I am trying to use the library as an expression builder so I can pass the expression's it builds around and make things more re-usable.
As such I really want access to CompleteExpression
because then I can create a Lambda and store that in a configuration object and apply it whenever i need to.
Ideally, everything in SearchBase should be public. It would be also nice if BuildExpression in QueryableSearchBase wasn't protected either.
Hey @VictorioBerra,
This is an interesting point and one I'm happy to discuss. Originally I coded this defensively as I did not invisage it being used beyond simply using the extension methods it exposes.
The fact you are using this to build expressions is great, but we should consider the change.
I agree @ninjanye. I really like everything in /Helpers too. Many of those don't really need to be Internal IMO because they are dependency free utilities that anyone could benefit from. I realize that the change I proposed would need some tweaking especially because I would love to trigger the finalExpression to be created without altering the queryable. Maybe we can some up with a new method so the library can expose a few useful things without dropping all the defenses you put in.
@ninjanye Imagine this as a super simplified usecase:
public class Program
{
public static void Main()
{
var p = new Product();
p.NameSearchPredicate = (new List<Product>()).AsQueryable()
.Search(x => x.Name)
.StartsWith("abc", "ninja")
.Containing("xyz", "extensions")
.FinalPredicate;
p.NameSearchPredicate = (new List<Product>()).AsQueryable()
.Search(x => x.Quantity)
.EqualTo(4, 5)
.FinalPredicate;
}
}
public class Product
{
public Expression<Func<Product, bool>> NameSearchPredicate { get; set; }
public string Name { get; set; }
public Expression<Func<Product, bool>> QuantitySearchPredicate { get; set; }
public int Quantity { get; set; }
}
Imagine an API like this:
var product = new Searchable<Product>();
var expression = product
.Search(x => x.Quantity)
.EqualTo(4, 5)
.BuildQueryablePredicate();
_context.Products.Where(expression).ToList();
It doesnt have to be complicated at first. You already have most of the work done, we just have to expose some of the internals in a nice way.
var expression = product.Search(x => x.Quantity)
.EqualTo(4, 5)
.BuildQueryablePredicate();
This captures the need perfectly, thank you. I'm tempted to remove the "Queryable" part from the method name to create a .BuildPredicate()
or even a ToPredicate()
method.
Further down the line, maybe this becomes a package of it's own (NinjaNye.PredicateBuilder ???), but for now, I think we can work out a way of exposing it through SearchExtensions
@ninjanye Thank you this is really going to help me move forward. The names are entirely up to you I just wanted something descriptive that made for a good example.