Skip to content

Commit e8444bc

Browse files
committed
- added enumerable extensions
1 parent 199c865 commit e8444bc

File tree

10 files changed

+225
-0
lines changed

10 files changed

+225
-0
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using NUnit.Framework;
5+
6+
namespace Shuttle.Core.Reflection.Tests
7+
{
8+
[TestFixture]
9+
public class EnumerableExtensionsFixture
10+
{
11+
private static IEnumerable<object> GetList()
12+
{
13+
return new List<object>
14+
{
15+
new SomeClass(),
16+
new SomeOtherClass(),
17+
new SomeOtherClass()
18+
};
19+
}
20+
21+
[Test]
22+
public void Should_be_able_to_find_a_single_instance()
23+
{
24+
Assert.IsNotNull(GetList().Find<ISomeClass>());
25+
Assert.IsNull(GetList().Find<EnumerableExtensionsFixture>());
26+
}
27+
28+
[Test]
29+
public void Should_be_able_to_find_all_instances()
30+
{
31+
Assert.AreEqual(2, GetList().FindAll<ISomeOtherClass>().Count());
32+
Assert.AreEqual(1, GetList().FindAll<ISomeClass>().Count());
33+
Assert.AreEqual(0, GetList().FindAll<EnumerableExtensionsFixture>().Count());
34+
}
35+
36+
[Test]
37+
public void Should_be_able_to_get_a_single_instance()
38+
{
39+
Assert.IsNotNull(GetList().Get<ISomeClass>());
40+
Assert.Throws<InvalidOperationException>(() => GetList().Get<EnumerableExtensionsFixture>());
41+
}
42+
}
43+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netcoreapp2.0</TargetFramework>
5+
</PropertyGroup>
6+
7+
<ItemGroup>
8+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
9+
<PackageReference Include="NUnit" Version="3.9.0" />
10+
<PackageReference Include="NUnit3TestAdapter" Version="3.9.0" />
11+
</ItemGroup>
12+
13+
<ItemGroup>
14+
<ProjectReference Include="..\Shuttle.Core.Reflection\Shuttle.Core.Reflection.csproj" />
15+
</ItemGroup>
16+
17+
</Project>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace Shuttle.Core.Reflection.Tests
2+
{
3+
public class SomeClass : ISomeClass
4+
{
5+
6+
}
7+
8+
public interface ISomeClass
9+
{
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace Shuttle.Core.Reflection.Tests
2+
{
3+
public class SomeOtherClass : ISomeOtherClass
4+
{
5+
6+
}
7+
8+
public interface ISomeOtherClass
9+
{
10+
}
11+
}

Shuttle.Core.Reflection.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
1111
README.md = README.md
1212
EndProjectSection
1313
EndProject
14+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Shuttle.Core.Reflection.Tests", "Shuttle.Core.Reflection.Tests\Shuttle.Core.Reflection.Tests.csproj", "{2FDC00C6-812F-4ED8-BFEC-361725777049}"
15+
EndProject
1416
Global
1517
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1618
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
2123
{8D0B93C0-CEDA-496C-A4D6-864AEBC0DBF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
2224
{8D0B93C0-CEDA-496C-A4D6-864AEBC0DBF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
2325
{8D0B93C0-CEDA-496C-A4D6-864AEBC0DBF2}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{2FDC00C6-812F-4ED8-BFEC-361725777049}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{2FDC00C6-812F-4ED8-BFEC-361725777049}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{2FDC00C6-812F-4ED8-BFEC-361725777049}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{2FDC00C6-812F-4ED8-BFEC-361725777049}.Release|Any CPU.Build.0 = Release|Any CPU
2430
EndGlobalSection
2531
GlobalSection(SolutionProperties) = preSolution
2632
HideSolutionNode = FALSE
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Shuttle.Core.Contract;
5+
6+
namespace Shuttle.Core.Reflection
7+
{
8+
public static class EnumerableExtensions
9+
{
10+
public static T Get<T>(this IEnumerable<object> list) where T : class
11+
{
12+
var result = Find<T>(list);
13+
14+
if (result == null)
15+
{
16+
throw new InvalidOperationException(string.Format(Resources.EnemerableNoMatchException,
17+
typeof(T).FullName));
18+
}
19+
20+
return result;
21+
}
22+
23+
public static T Find<T>(this IEnumerable<object> list) where T : class
24+
{
25+
var matches = FindAll<T>(list).ToList();
26+
27+
if (matches.Count > 1)
28+
{
29+
throw new InvalidOperationException(string.Format(Resources.EnumerableFoundTooManyException,
30+
matches.Count, typeof(T).FullName));
31+
}
32+
33+
return matches.Count == 1
34+
? matches[0]
35+
: null;
36+
}
37+
38+
public static IEnumerable<T> FindAll<T>(this IEnumerable<object> list) where T : class
39+
{
40+
Guard.AgainstNull(list, nameof(list));
41+
42+
var type = typeof(T);
43+
44+
return (from o in list
45+
where o.GetType().IsAssignableTo(type)
46+
select (T)o).ToList();
47+
}
48+
}
49+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using Shuttle.Core.Contract;
5+
6+
namespace Shuttle.Core.Reflection
7+
{
8+
public static class ExceptionExtensions
9+
{
10+
public static string AllMessages(this Exception ex)
11+
{
12+
var messages = new StringBuilder();
13+
14+
var enumerator = ex;
15+
16+
while (enumerator != null)
17+
{
18+
messages.AppendFormat("{0}{1}", messages.Length > 0 ? " / " : string.Empty, enumerator.Message);
19+
20+
enumerator = enumerator.InnerException;
21+
}
22+
23+
return messages.ToString();
24+
}
25+
26+
public static Exception TrimLeading<T>(this Exception ex) where T : Exception
27+
{
28+
Guard.AgainstNull(ex, nameof(ex));
29+
30+
var trim = typeof(T);
31+
32+
var exception = ex;
33+
34+
while (exception.GetType() == trim)
35+
{
36+
if (exception.InnerException == null)
37+
{
38+
break;
39+
}
40+
41+
exception = exception.InnerException;
42+
}
43+
44+
return exception;
45+
}
46+
}
47+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
3+
namespace Shuttle.Core.Reflection
4+
{
5+
public static class ObjectExtensions
6+
{
7+
public static void AttemptDispose(this object o)
8+
{
9+
if (o is IDisposable disposable)
10+
{
11+
disposable.Dispose();
12+
}
13+
}
14+
}
15+
}

Shuttle.Core.Reflection/Resources.Designer.cs

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Shuttle.Core.Reflection/Resources.resx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@
121121
<value>[GetAssembly] : could not load assembly '{0}' / exception = {1}</value>
122122
<comment>{0} = assembly, {1} = exception</comment>
123123
</data>
124+
<data name="EnemerableNoMatchException" xml:space="preserve">
125+
<value>Enumerable contained no elements matching type '{0}'.</value>
126+
<comment>{0} = type sought</comment>
127+
</data>
128+
<data name="EnumerableFoundTooManyException" xml:space="preserve">
129+
<value>Enumerable contains {0} elements matching type '{1}'.</value>
130+
<comment>{0} = count found, {1} = type sought</comment>
131+
</data>
124132
<data name="GetFileNameWithoutExtensionException" xml:space="preserve">
125133
<value>Returned null from call to 'GetFileNameWithoutExtension' for value '{0}'.</value>
126134
<comment>{0} = path</comment>

0 commit comments

Comments
 (0)