Skip to content

Commit

Permalink
Fixes #7 - Added a way to add configuration to your host without modi…
Browse files Browse the repository at this point in the history
…fying the core host
  • Loading branch information
Jetski5822 committed Aug 24, 2015
1 parent 5719a9a commit ccbcf03
Show file tree
Hide file tree
Showing 17 changed files with 193 additions and 146 deletions.
66 changes: 60 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,73 @@
Brochard
========
# Brochard

Orchard CMS running on ASP.Net VNext (DNX)
Brochard is the implementation of Orchard CMS in Asp.Net VNext (also known as DNX)

Getting Started
---------------
## Getting Started

First off, follow the instructions here https://github.com/aspnet/home in order to install DNVM. Next install Visual Studio 2015, or what ever you flavour of editor is.

Next you want to clone the Repo. 'git clone https://github.com/OrchardCMS/Brochard.git' and checkout the master branch.

Run the build.cmd file included in the repository to bootstrap dnx and build solution.
Run the build.cmd file included in the repository to bootstrap DNX and build solution.

Next navigate to 'D:\Brochard\src\OrchardVNext.Web' or where ever your retrospective folder is on the command line in Administrative mode.

run.. 'dnx web' -> Hey you just kicked up the Orchard host.

Then in your browser, call the url... http://localhost:5001/setup/index

## Using Brochard

### Creating a host

When running Brochard, you need a client. The default implementation is to have a client talk to a host.

The client is any project that creates the host.

To create the host in a web project you would do

```c#
public class Startup {
public IServiceProvider ConfigureServices(IServiceCollection services) {
return services
// AddHostSample is where the magic is done. This extension method lives in the Host (OrchardVNext.Hosting.Web)
.AddHostSample()
.BuildServiceProvider();
}
}
```

The Host has a small wrapper


```c#
public static IServiceCollection AddHostSample([NotNull] this IServiceCollection services) {
// This will setup all your core services for a host
return services.AddHost(internalServices => {
// The core of the host
internalServices.AddHostCore();
///... All extra things you want registered so that you don't have to touch the core host.
});
```

### Additional module locations

Additional locations for module discovery can be added in your host setup.

```c#
public static IServiceCollection AddHostSample([NotNull] this IServiceCollection services) {
return services.AddHost(internalServices => {
internalServices.AddHostCore();

internalServices.Configure<ExtensionHarvestingOptions>(options => {
var expander = new ModuleLocationExpander(
DefaultExtensionTypes.Module,
new[] { "~/Core/OrchardVNext.Core", "~/Modules" },
"Module.txt"
);

options.ModuleLocationExpanders.Add(expander);
});
});
}
```
89 changes: 12 additions & 77 deletions src/OrchardVNext.DependencyInjection/OrchardLibraryManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,25 @@
using Microsoft.Dnx.Runtime;

namespace OrchardVNext.DependencyInjection {
public interface IOrchardLibraryManager : ILibraryManager, ILibraryExporter {
IList<IMetadataReference> MetadataReferences { get; }
public interface IOrchardLibraryManager : ILibraryManager {
void AddLibrary(Library library);
void AddAdditionalLibraryExportRegistrations(string name, LibraryExport additionalRegistration);
void AddMetadataReference(IMetadataReference metadataReference);
IMetadataReference GetMetadataReference(string name);
IEnumerable<IMetadataReference> GetAllMetadataReferences();
}

public class OrchardLibraryManager : IOrchardLibraryManager {
private readonly ILibraryManager _libraryManager;
private readonly ILibraryExporter _libraryExporter;

public OrchardLibraryManager(ILibraryManager libraryManager, ILibraryExporter libraryExporter) {
public OrchardLibraryManager(ILibraryManager libraryManager) {
_libraryManager = libraryManager;
_libraryExporter = libraryExporter;

AdditionalLibraries = new List<Library>();
AdditionalLibraryExportRegistrations = new Dictionary<string, LibraryExport>();
MetadataReferences = new List<IMetadataReference>();
}

private IList<Library> AdditionalLibraries { get; }
public IDictionary<string, LibraryExport> AdditionalLibraryExportRegistrations { get; }
public IList<IMetadataReference> MetadataReferences { get; }
private IList<IMetadataReference> MetadataReferences { get; }

public void AddLibrary(Library library) {
if (AdditionalLibraries.Any(lib => lib.Name == library.Name))
Expand All @@ -35,17 +31,20 @@ public void AddLibrary(Library library) {
AdditionalLibraries.Add(library);
}

public void AddAdditionalLibraryExportRegistrations(string name, LibraryExport additionalRegistration) {
AdditionalLibraryExportRegistrations[name] = additionalRegistration;
}

public void AddMetadataReference(IMetadataReference metadataReference) {
if (MetadataReferences.Any(x => x.Name == metadataReference.Name))
return;

MetadataReferences.Add(metadataReference);
}

public IMetadataReference GetMetadataReference(string name) {
return MetadataReferences.SingleOrDefault(x => x.Name == name);
}

public IEnumerable<IMetadataReference> GetAllMetadataReferences() {
return MetadataReferences;
}

public IEnumerable<Library> GetReferencingLibraries(string name) {
return _libraryManager.GetReferencingLibraries(name)
Expand All @@ -66,69 +65,5 @@ public IEnumerable<Library> GetLibraries() {
.GetLibraries()
.Concat(AdditionalLibraries);
}

public LibraryExport GetExport(string name) {
var export = _libraryExporter.GetExport(name);
if (export != null)
return export;

if (AdditionalLibraryExportRegistrations.Any(x => x.Key == name))
return AdditionalLibraryExportRegistrations.Single(x => x.Key == name).Value;

return null;
}

public LibraryExport GetExport(string name, string aspect) {
var export = _libraryExporter.GetExport(name, aspect);
if (export != null)
return export;

if (AdditionalLibraryExportRegistrations.Any(x => x.Key == name))
return AdditionalLibraryExportRegistrations.Single(x => x.Key == name).Value;

return null;
}

public LibraryExport GetAllExports(string name) {
var internalExports = _libraryExporter.GetAllExports(name);

return new LibraryExportWrapper(internalExports,
AdditionalLibraryExportRegistrations.Select(x => x.Value).ToList());
}

public LibraryExport GetAllExports(string name, string aspect) {
var internalExports = _libraryExporter.GetAllExports(name, aspect);

return new LibraryExportWrapper(internalExports,
AdditionalLibraryExportRegistrations.Select(x => x.Value).ToList());
}

private class LibraryExportWrapper : LibraryExport {
public LibraryExportWrapper(
LibraryExport internalExports, IReadOnlyList<LibraryExport> additionalExports)
: base(JoinMetadataReferences(internalExports, additionalExports),
JoinSourceReferences(internalExports, additionalExports)) {
}

private static IList<ISourceReference> JoinSourceReferences(
LibraryExport internalExports,
IReadOnlyList<LibraryExport> additionalExports) {
return internalExports
.SourceReferences
.AsEnumerable()
.Concat(
additionalExports.SelectMany(x => x.SourceReferences)).ToList();
}

private static IList<IMetadataReference> JoinMetadataReferences(
LibraryExport internalExports,
IReadOnlyList<LibraryExport> additionalExports) {
return internalExports
.MetadataReferences
.AsEnumerable()
.Concat(
additionalExports.SelectMany(x => x.MetadataReferences)).ToList();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using Microsoft.Framework.DependencyInjection;
using OrchardVNext.Abstractions.Environment;
using OrchardVNext.FileSystem;
using OrchardVNext.Hosting.Extensions.Folders;
using OrchardVNext.Hosting.Extensions.Models;

namespace OrchardVNext.Hosting {
public static class ServiceCollectionExtensions {
Expand All @@ -9,8 +11,19 @@ public static IServiceCollection AddWeb([NotNull] this IServiceCollection servic
internalServices.AddLogging();
internalServices.AddHostCore();
internalServices.AddWebFileSystems();
internalServices.Configure<ExtensionHarvestingOptions>(options => {
var expander = new ModuleLocationExpander(
DefaultExtensionTypes.Module,
new[] { "~/Core/OrchardVNext.Core", "~/Modules" },
"Module.txt"
);
options.ModuleLocationExpanders.Add(expander);
});
internalServices.AddWebFileSystems();
internalServices.AddSingleton<IHostEnvironment, WebHostEnvironment>();
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ public class DefaultRoslynCompilationService : ICompilationService {
private readonly ConcurrentDictionary<string, AssemblyMetadata> _metadataFileCache =
new ConcurrentDictionary<string, AssemblyMetadata>(StringComparer.OrdinalIgnoreCase);

private readonly IOrchardLibraryManager _libraryExporter;
private readonly ILibraryExporter _libraryExporter;
private readonly IOrchardLibraryManager _libraryManager;
private readonly IApplicationEnvironment _environment;
private readonly IAssemblyLoadContext _loader;
private readonly ICompilerOptionsProvider _compilerOptionsProvider;
Expand All @@ -50,13 +51,15 @@ public class DefaultRoslynCompilationService : ICompilationService {
/// <param name="host">The <see cref="IMvcRazorHost"/> that was used to generate the code.</param>
public DefaultRoslynCompilationService(IApplicationEnvironment environment,
IAssemblyLoadContextAccessor loaderAccessor,
IOrchardLibraryManager libraryExporter,
ILibraryExporter libraryExporter,
IOrchardLibraryManager libraryManager,
ICompilerOptionsProvider compilerOptionsProvider,
IMvcRazorHost host,
IOptions<RazorViewEngineOptions> optionsAccessor) {
_environment = environment;
_loader = loaderAccessor.GetLoadContext(typeof(DefaultRoslynCompilationService).GetTypeInfo().Assembly);
_libraryExporter = libraryExporter;
_libraryManager = libraryManager;
_applicationReferences = new Lazy<List<MetadataReference>>(GetApplicationReferences);
_compilerOptionsProvider = compilerOptionsProvider;
_fileProvider = optionsAccessor.Options.FileProvider;
Expand Down Expand Up @@ -173,8 +176,8 @@ private List<MetadataReference> GetApplicationReferences() {
references.AddRange(compilationReference.Compilation.References);
references.Add(roslynReference.MetadataReference);

references.AddRange(_libraryExporter
.MetadataReferences
references.AddRange(_libraryManager
.GetAllMetadataReferences()
.OfType<IRoslynMetadataReference>()
.Select(x => x.MetadataReference));

Expand Down
2 changes: 1 addition & 1 deletion src/OrchardVNext.Hosting.Web/OrchardContainerMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs a
_logger.LogDebug("Resolving {0}", assemblyName);
var reference = _libraryManager.MetadataReferences.FirstOrDefault(x => x.Name == assemblyName.Name);
var reference = _libraryManager.GetMetadataReference(assemblyName.Name);
if (reference != null) {
if (reference is MetadataFileReference) {
Expand Down
8 changes: 4 additions & 4 deletions src/OrchardVNext.Hosting/Extensions/ExtensionManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@

namespace OrchardVNext.Hosting.Extensions {
public class ExtensionManager : IExtensionManager {
private readonly IEnumerable<IExtensionFolders> _folders;
private readonly IExtensionLocator _extensionLocator;
private readonly IEnumerable<IExtensionLoader> _loaders;
private readonly ILogger _logger;

public Localizer T { get; set; }

public ExtensionManager(
IEnumerable<IExtensionFolders> folders,
IExtensionLocator extensionLocator,
IEnumerable<IExtensionLoader> loaders,
ILoggerFactory loggerFactory) {

_folders = folders;
_extensionLocator = extensionLocator;
_loaders = loaders.OrderBy(x => x.Order).ToArray();
_logger = loggerFactory.CreateLogger<ExtensionManager>();
T = NullLocalizer.Instance;
Expand All @@ -37,7 +37,7 @@ public ExtensionDescriptor GetExtension(string id) {
}

public IEnumerable<ExtensionDescriptor> AvailableExtensions() {
return _folders.SelectMany(x => x.AvailableExtensions()).ToList();
return _extensionLocator.AvailableExtensions().ToList();
}

public IEnumerable<FeatureDescriptor> AvailableFeatures() {
Expand Down
19 changes: 0 additions & 19 deletions src/OrchardVNext.Hosting/Extensions/Folders/CoreModuleFolders.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public IEnumerable<ExtensionDescriptor> HarvestExtensions(IEnumerable<string> pa
}

private IEnumerable<ExtensionDescriptor> HarvestExtensions(string path, string extensionType, string manifestName, bool manifestIsOptional) {
string key = string.Format("{0}-{1}-{2}", path, manifestName, extensionType);
return AvailableExtensionsInFolder(path, extensionType, manifestName, manifestIsOptional).ToReadOnlyCollection();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Collections.Generic;

namespace OrchardVNext.Hosting.Extensions.Folders {
public class ExtensionHarvestingOptions {
public IList<IModuleLocationExpander> ModuleLocationExpanders { get; }
= new List<IModuleLocationExpander>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Microsoft.Framework.OptionsModel;

namespace OrchardVNext.Hosting.Extensions.Folders {
/// <summary>
/// Sets up default options for <see cref="ExtensionHarvestingOptions"/>.
/// </summary>
public class ExtensionHarvestingOptionsSetup : ConfigureOptions<ExtensionHarvestingOptions> {
/// <summary>
/// Initializes a new instance of <see cref="ExtensionHarvestingOptions"/>.
/// </summary>
public ExtensionHarvestingOptionsSetup()
: base(options => { }) {
Order = -1000;
}
}
}
24 changes: 24 additions & 0 deletions src/OrchardVNext.Hosting/Extensions/Folders/ExtensionLocator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Collections.Generic;
using System.Linq;
using OrchardVNext.Hosting.Extensions.Models;
using Microsoft.Framework.OptionsModel;

namespace OrchardVNext.Hosting.Extensions.Folders {
public class ExtensionLocator : IExtensionLocator {
private readonly IOptions<ExtensionHarvestingOptions> _optionsAccessor;
private readonly IExtensionHarvester _extensionHarvester;

public ExtensionLocator(
[NotNull] IOptions<ExtensionHarvestingOptions> optionsAccessor,
[NotNull] IExtensionHarvester extensionHarvester) {
_optionsAccessor = optionsAccessor;
_extensionHarvester = extensionHarvester;
}

public IEnumerable<ExtensionDescriptor> AvailableExtensions() {
return _optionsAccessor.Options.ModuleLocationExpanders
.SelectMany(x => _extensionHarvester.HarvestExtensions(
x.SearchPaths, x.ExtensionType, x.ManifestName, x.ManifestOptional));
}
}
}
Loading

0 comments on commit ccbcf03

Please sign in to comment.