Skip to content

Commit 897395c

Browse files
committed
Lookup not only publicly visible methods but private methods as well
1 parent a07ff48 commit 897395c

File tree

2 files changed

+104
-2
lines changed

2 files changed

+104
-2
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Licensed to the Xtensive LLC under one or more agreements.
2+
// The Xtensive LLC licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using System;
6+
using System.Collections.Generic;
7+
using System.Linq;
8+
using NUnit.Framework;
9+
using Xtensive.Orm.Configuration;
10+
11+
namespace Xtensive.Orm.Tests.Issues
12+
{
13+
namespace MaterializationMethodTestsModel
14+
{
15+
[HierarchyRoot]
16+
public class Person : Entity
17+
{
18+
public Person(Session session) : base(session) { }
19+
20+
[Field, Key]
21+
public int Id { get; private set; }
22+
23+
[Field]
24+
public string Name { get; set; }
25+
}
26+
27+
}
28+
29+
public class PersonModel
30+
{
31+
public int Id { get; set; }
32+
public string Name { get; set; }
33+
}
34+
35+
public abstract class ServiceBase<TEntity, TModel> where TModel: class, new() where TEntity: class, IEntity
36+
{
37+
public IList<TModel> GetAllViaPrivate(Session session) =>
38+
session.Query.All<TEntity>().Select(i => PrivateSelect(i)).ToList();
39+
40+
public IList<TModel> GetAllViaPublic(Session session) =>
41+
session.Query.All<TEntity>().Select(i => PublicSelect(i)).ToList();
42+
43+
public IList<TModel> GetAllViaProtected(Session session) =>
44+
session.Query.All<TEntity>().Select(i => ProtectedSelect(i)).ToList();
45+
46+
public IList<TModel> GetAllViaInternal(Session session) =>
47+
session.Query.All<TEntity>().Select(i => InternalSelect(i)).ToList();
48+
49+
public IList<TModel> GetAllViaProtectedInternal(Session session) =>
50+
session.Query.All<TEntity>().Select(i => ProtectedInternalSelect(i)).ToList();
51+
52+
private TModel PrivateSelect(TEntity entity) => ProtectedSelect(entity);
53+
public TModel PublicSelect(TEntity entity) => ProtectedSelect(entity);
54+
internal TModel InternalSelect(TEntity entity) => ProtectedSelect(entity);
55+
protected internal TModel ProtectedInternalSelect(TEntity entity) => ProtectedSelect(entity);
56+
57+
protected abstract TModel ProtectedSelect(TEntity entity);
58+
}
59+
60+
public class PersonService : ServiceBase<MaterializationMethodTestsModel.Person, PersonModel>
61+
{
62+
protected override PersonModel ProtectedSelect(MaterializationMethodTestsModel.Person entity) =>
63+
new PersonModel { Id = entity.Id, Name = entity.Name };
64+
}
65+
66+
public class ServiceMaterializationMethodTests : AutoBuildTest
67+
{
68+
protected override DomainConfiguration BuildConfiguration()
69+
{
70+
var configuration = base.BuildConfiguration();
71+
var personType = typeof(MaterializationMethodTestsModel.Person);
72+
configuration.Types.Register(personType.Assembly, personType.Namespace);
73+
return configuration;
74+
}
75+
76+
private static IEnumerable<(string, Func<PersonService, Session, IList<PersonModel>>)> DataExtractorMethods()
77+
{
78+
yield return (nameof(PersonService.GetAllViaPrivate), (service, session) => service.GetAllViaPrivate(session));
79+
yield return (nameof(PersonService.GetAllViaPublic), (service, session) => service.GetAllViaPublic(session));
80+
yield return (nameof(PersonService.GetAllViaInternal), (service, session) => service.GetAllViaInternal(session));
81+
yield return
82+
(nameof(PersonService.GetAllViaProtected), (service, session) => service.GetAllViaProtected(session));
83+
yield return
84+
(nameof(PersonService.GetAllViaProtectedInternal),
85+
(service, session) => service.GetAllViaProtectedInternal(session));
86+
}
87+
88+
[TestCaseSource(nameof(DataExtractorMethods))]
89+
public void MaterializationByMethodOfBaseService(
90+
(string name, Func<PersonService, Session, IList<PersonModel>> getPeopleMethod) testCase)
91+
{
92+
using var session = Domain.OpenSession();
93+
using var _ = session.OpenTransaction();
94+
var personService = new PersonService();
95+
var people = testCase.getPeopleMethod(personService, session);
96+
Assert.AreEqual(0, people.Count);
97+
}
98+
}
99+
}

Orm/Xtensive.Orm/Orm/Linq/MemberCompilation/MemberCompilerProvider.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,11 @@ private static MemberInfo GetCanonicalMember(MemberInfo member)
338338
targetType = targetType.GetGenericTypeDefinition();
339339
if (canonicalMember is FieldInfo)
340340
canonicalMember = targetType.GetField(canonicalMember.Name);
341-
else if (canonicalMember is MethodInfo)
342-
canonicalMember = GetCanonicalMethod((MethodInfo) canonicalMember, targetType.GetMethods());
341+
else if (canonicalMember is MethodInfo methodInfo) {
342+
const BindingFlags methodBindingFlags =
343+
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
344+
canonicalMember = GetCanonicalMethod(methodInfo, targetType.GetMethods(methodBindingFlags));
345+
}
343346
else if (canonicalMember is ConstructorInfo)
344347
canonicalMember = GetCanonicalMethod((ConstructorInfo) canonicalMember, targetType.GetConstructors());
345348
else

0 commit comments

Comments
 (0)