3
\$\begingroup\$

How do you list your referenced solution assemblies for IoC registration? I was really tired of typing something strange as new [] { typeof(SomeType).Assembly, ... }. What do you think about the following approach?

Use case:

class Program
{
 static void Main(string[] args)
 {
 foreach (var a in Solution.Assemblies)
 Console.WriteLine(a); 
 }
}

Where Solution.Assemblies is:

public static class Solution 
{
 static IEnumerable<string> AssemblyNames => new[] {
 "ValueCache", "ValueCache.Tests", "LazyProxies", "ConsoleApplication1", "ClassLibrary1"
 };
 public static IEnumerable<Assembly> Assemblies => AssemblyNames
 .Select(an => Load(an))
 .Where(a => a != null);
 [DebuggerHidden]
 static Assembly Load(string assemblyName)
 {
 try
 {
 return Assembly.Load(new AssemblyName(assemblyName));
 }
 catch
 {
 return null;
 }
 }
}

... being generated by Solution.tt file:

<#@ template debug="false" hostSpecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="EnvDte" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Diagnostics" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Collections" #>
<#@ import namespace="System.Collections.Generic" #> 
<#@ import namespace="System.Reflection" #> 
<#@ import namespace="EnvDTE" #> 
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
namespace SolutionConfiguration
{
 public static class Solution 
 {
 static IEnumerable<string> AssemblyNames => new[] {
 <#= String.Join(", ", from name in new SolutionAssemblyNames(Host)
 select $"\"{name}\"") #>
 };
 public static IEnumerable<Assembly> Assemblies => AssemblyNames
 .Select(an => Load(an))
 .Where(a => a != null);
 [DebuggerHidden]
 static Assembly Load(string assemblyName)
 {
 try
 {
 return Assembly.Load(new AssemblyName(assemblyName));
 }
 catch
 {
 return null;
 }
 }
 }
}
<#+
 class SolutionAssemblyNames : IEnumerable<string>
 {
 public SolutionAssemblyNames(ITextTemplatingEngineHost host)
 {
 Host = host;
 }
 public IEnumerator<string> GetEnumerator() => Assemblies.GetEnumerator();
 IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 IEnumerable<string> Assemblies => Projects
 .Select(p => p?.Properties?.Item("AssemblyName")?.Value as string)
 .Distinct().Where(a => !string.IsNullOrWhiteSpace(a));
 IEnumerable<Project> Projects => VisualStudio.Solution.Projects.OfType<Project>();
 DTE VisualStudio => (Host as IServiceProvider).GetService(typeof(DTE)) as DTE;
 ITextTemplatingEngineHost Host { get; }
 }
#>
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked May 26, 2016 at 5:42
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

This is a fascinating solution. I kept looking at it and thinking "There must be an easier way!" but every possible solution I came up with had a fatal flaw.

All I really have, then, is nitpicking:

public static IEnumerable<Assembly> Assemblies => AssemblyNames
 .Select(an => Load(an))

Can be simplified to:

public static IEnumerable<Assembly> Assemblies => AssemblyNames
 .Select(Load)

SolutionAssemblyNames is looking fairly dense. I'd add 1 line of whitespace between each property to make it a bit more readable.

answered Dec 20, 2017 at 16:58
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.