zoukankan      html  css  js  c++  java
  • Orchard CMS中如何打包不带源码的模块

    Orchard CMS中如何打包不带源码的模块

    在Orchard CMS的官网已经提供了文档说明如何打包,但是如果使用它的打包方式,打好的nuget包是带源代码的。如果是为开源系统写模块,不需要关注源代码是否可见。但是如果是用Orchard CMS作为商业用途,那么可能你需要阅读这边文章啦。

    1.获取打包文件的原理:

    简单说一下Orchard打包模块获取需要打包的文件的原理:控制台传入模块名称,通过找到对应模块的.csproj来分析需要打包的文件,每个.csproj中的ItemGroup节点下的文件就是需要打包的文件

    image

    所有的文件名和地址都封装成为IPackageFile,

    image

    最终使用NuGet的打包管理工具进行打包。

    Orchard默认提供的打包程序都会把源代码打入包内,有时候我们需要不带源代码的NuGet包,所以就需要把Orchard.Package模块的PackageBuilder类改造一下下。

    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
    public class PackageBuilder : IPackageBuilder {
    private readonly IWebSiteFolder _webSiteFolder;
    private readonly IVirtualPathProvider _virtualPathProvider;
    private readonly IOrchardFrameworkAssemblies _frameworkAssemblies;
     
    private static readonly string[] _ignoredThemeExtensions = new[] {
    "obj", "pdb", "exclude"
    };
     
    private static readonly string[] _ignoredThemePaths = new[] {
    "/obj/"
    };
     
    private static bool IgnoreFile(string filePath) {
    return String.IsNullOrEmpty(filePath) ||
    _ignoredThemePaths.Any(filePath.Contains) ||
    _ignoredThemeExtensions.Contains(Path.GetExtension(filePath) ?? "");
    }
     
    public PackageBuilder(IWebSiteFolder webSiteFolder,
    IVirtualPathProvider virtualPathProvider,
    IOrchardFrameworkAssemblies frameworkAssemblies) {
     
    _webSiteFolder = webSiteFolder;
    _virtualPathProvider = virtualPathProvider;
    _frameworkAssemblies = frameworkAssemblies;
    }
     
    public Stream BuildPackage(ExtensionDescriptor extensionDescriptor) {
    var context = new CreateContext();
    BeginPackage(context);
    try {
    EstablishPaths(context, _webSiteFolder, extensionDescriptor.Location, extensionDescriptor.Id, extensionDescriptor.ExtensionType);
    SetCoreProperties(context, extensionDescriptor);
     
    string projectFile = extensionDescriptor.Id + ".csproj";
    string assemblyFile = string.Format("bin/{0}.dll", extensionDescriptor.Id);
    if (LoadProject(context, projectFile)) {
    EmbedVirtualFile(context, assemblyFile, MediaTypeNames.Application.Octet);
    EmbedProjectFiles(context, "Content", "None", "EmbeddedResource");
    EmbedReferenceFiles(context);
    } else if (DefaultExtensionTypes.IsTheme(extensionDescriptor.ExtensionType)) {
    // this is a simple theme with no csproj
    EmbedThemeFiles(context);
    }
    }
    finally {
    EndPackage(context);
    }
     
    if (context.Stream.CanSeek) {
    context.Stream.Seek(0, SeekOrigin.Begin);
    }
     
    return context.Stream;
    }
     
    public static string BuildPackageId(string extensionName, string extensionType) {
    return PackagingSourceManager.GetExtensionPrefix(extensionType) + extensionName;
    }
     
    private static void SetCoreProperties(CreateContext context, ExtensionDescriptor extensionDescriptor) {
    context.Builder.Id = BuildPackageId(extensionDescriptor.Id, extensionDescriptor.ExtensionType);
    context.Builder.Version = new Version(extensionDescriptor.Version);
    context.Builder.Title = extensionDescriptor.Name ?? extensionDescriptor.Id;
    context.Builder.Description = extensionDescriptor.Description;
    context.Builder.Authors.Add(extensionDescriptor.Author);
     
    if(Uri.IsWellFormedUriString(extensionDescriptor.WebSite, UriKind.Absolute)) {
    context.Builder.ProjectUrl = new Uri(extensionDescriptor.WebSite);
    }
    }
     
    private static void EmbedProjectFiles(CreateContext context, params string[] itemGroupTypes) {
    IEnumerable<XElement> itemGroups = context.Project
    .Elements(Ns("Project"))
    .Elements(Ns("ItemGroup"));
     
    foreach (string itemGroupType in itemGroupTypes) {
    IEnumerable<string> includePaths = itemGroups
    .Elements(Ns(itemGroupType))
    .Attributes("Include")
    .Select(x => x.Value);
    foreach (string includePath in includePaths) {
    EmbedVirtualFile(context, includePath, MediaTypeNames.Application.Octet);
    }
    }
    }
     
    private void EmbedReferenceFiles(CreateContext context) {
    var entries = context.Project
    .Elements(Ns("Project"))
    .Elements(Ns("ItemGroup"))
    .Elements(Ns("Reference"))
    .Select(reference => new {
    Include = reference.Attribute("Include"),
    HintPath = reference.Element(Ns("HintPath"))
    })
    .Where(entry => entry.Include != null);
     
    foreach (var entry in entries) {
    var assemblyName = new AssemblyName(entry.Include.Value);
     
    // If it is not a core assembly
    if (_frameworkAssemblies.GetFrameworkAssemblies().FirstOrDefault(assembly => assembly.Name.Equals(assemblyName.Name)) == null) {
    string virtualPath = _virtualPathProvider.GetReferenceVirtualPath(context.SourcePath, assemblyName.Name, entry.HintPath != null ? entry.HintPath.Value : null);
     
    if (!string.IsNullOrEmpty(virtualPath)) {
    EmbedVirtualFile(context, virtualPath, MediaTypeNames.Application.Octet);
    }
    }
    }
    }
     
    private static void EmbedThemeFiles(CreateContext context) {
    var basePath = context.SourcePath;
    foreach (var virtualPath in context.SourceFolder.ListFiles(context.SourcePath, true)) {
    // ignore dlls, etc
    if (IgnoreFile(virtualPath)) {
    continue;
    }
    // full virtual path given but we need the relative path so it can be put into
    // the package that way (the package itself is the logical base path).
    // Get it by stripping the basePath off including the slash.
    var relativePath = virtualPath.Replace(basePath, "");
    EmbedVirtualFile(context, relativePath, MediaTypeNames.Application.Octet);
    }
    }
     
    private static XName Ns(string localName) {
    return XName.Get(localName, "http://schemas.microsoft.com/developer/msbuild/2003");
    }
     
     
    private static void BeginPackage(CreateContext context) {
    context.Stream = new MemoryStream();
    context.Builder = new NuGetPackageBuilder();
    }
     
    private static void EstablishPaths(CreateContext context, IWebSiteFolder webSiteFolder, string locationPath, string moduleName, string moduleType) {
    context.SourceFolder = webSiteFolder;
    if (DefaultExtensionTypes.IsTheme(moduleType)) {
    context.SourcePath = "~/Themes/" + moduleName + "/";
    context.TargetPath = "\Content\Themes\" + moduleName + "\";
    }
    else {
    context.SourcePath = "~/Modules/" + moduleName + "/";
    context.TargetPath = "\Content\Modules\" + moduleName + "\";
    }
    }
     
    private static bool LoadProject(CreateContext context, string relativePath) {
    string virtualPath = context.SourcePath + relativePath;
    if (context.SourceFolder.FileExists(virtualPath)) {
    context.Project = XDocument.Parse(context.SourceFolder.ReadFile(context.SourcePath + relativePath));
    return true;
    }
    return false;
    }
     
    private static void EmbedVirtualFile(CreateContext context, string relativePath, string contentType) {
    var file = new VirtualPackageFile(
    context.SourceFolder,
    context.SourcePath + relativePath,
    context.TargetPath + relativePath);
    context.Builder.Files.Add(file);
    }
     
    private static void EndPackage(CreateContext context) {
    context.Builder.Save(context.Stream);
    }
     
    #region Nested type: CreateContext
     
    private class CreateContext {
    public Stream Stream { get; set; }
    public NuGetPackageBuilder Builder { get; set; }
     
    public IWebSiteFolder SourceFolder { get; set; }
    public string SourcePath { get; set; }
    public string TargetPath { get; set; }
     
    public XDocument Project { get; set; }
    }
     
    #endregion
     
    #region Nested type: CreateContext
     
    private class VirtualPackageFile : IPackageFile {
    private readonly IWebSiteFolder _webSiteFolder;
    private readonly string _virtualPath;
    private readonly string _packagePath;
     
    public VirtualPackageFile(IWebSiteFolder webSiteFolder, string virtualPath, string packagePath) {
    _webSiteFolder = webSiteFolder;
    _virtualPath = virtualPath;
    _packagePath = packagePath;
    }
     
    public string Path { get { return _packagePath; } }
     
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Supposed to return an open stream.")]
    public Stream GetStream() {
    var stream = new MemoryStream();
    _webSiteFolder.CopyFileTo(_virtualPath, stream);
    stream.Seek(0, SeekOrigin.Begin);
    return stream;
    }
    }
     
    #endregion
    }
    view rawgistfile1.cs hosted with ❤ by GitHub
    123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
    public class PackageBuilder : IPackageBuilder {
    private readonly IWebSiteFolder _webSiteFolder;
    private readonly IVirtualPathProvider _virtualPathProvider;
    private readonly IOrchardFrameworkAssemblies _frameworkAssemblies;
     
    private static readonly string[] _ignoredThemeExtensions = new[] {
    "obj", "pdb", "exclude"
    };
     
    private static readonly string[] _ignoredThemePaths = new[] {
    "/obj/"
    };
     
    private static bool IgnoreFile(string filePath) {
    return String.IsNullOrEmpty(filePath) ||
    _ignoredThemePaths.Any(filePath.Contains) ||
    _ignoredThemeExtensions.Contains(Path.GetExtension(filePath) ?? "");
    }
     
    public PackageBuilder(IWebSiteFolder webSiteFolder,
    IVirtualPathProvider virtualPathProvider,
    IOrchardFrameworkAssemblies frameworkAssemblies) {
     
    _webSiteFolder = webSiteFolder;
    _virtualPathProvider = virtualPathProvider;
    _frameworkAssemblies = frameworkAssemblies;
    }
     
    public Stream BuildPackage(ExtensionDescriptor extensionDescriptor) {
    var context = new CreateContext();
    BeginPackage(context);
    try {
    EstablishPaths(context, _webSiteFolder, extensionDescriptor.Location, extensionDescriptor.Id, extensionDescriptor.ExtensionType);
    SetCoreProperties(context, extensionDescriptor);
     
    string projectFile = extensionDescriptor.Id + ".csproj";
    string assemblyFile = string.Format("bin/{0}.dll", extensionDescriptor.Id);
    if (LoadProject(context, projectFile)) {
    EmbedVirtualFile(context, assemblyFile, MediaTypeNames.Application.Octet);
    EmbedProjectFiles(context, "Content", "None", "EmbeddedResource");
    EmbedReferenceFiles(context);
    } else if (DefaultExtensionTypes.IsTheme(extensionDescriptor.ExtensionType)) {
    // this is a simple theme with no csproj
    EmbedThemeFiles(context);
    }
    }
    finally {
    EndPackage(context);
    }
     
    if (context.Stream.CanSeek) {
    context.Stream.Seek(0, SeekOrigin.Begin);
    }
     
    return context.Stream;
    }
     
    public static string BuildPackageId(string extensionName, string extensionType) {
    return PackagingSourceManager.GetExtensionPrefix(extensionType) + extensionName;
    }
     
    private static void SetCoreProperties(CreateContext context, ExtensionDescriptor extensionDescriptor) {
    context.Builder.Id = BuildPackageId(extensionDescriptor.Id, extensionDescriptor.ExtensionType);
    context.Builder.Version = new Version(extensionDescriptor.Version);
    context.Builder.Title = extensionDescriptor.Name ?? extensionDescriptor.Id;
    context.Builder.Description = extensionDescriptor.Description;
    context.Builder.Authors.Add(extensionDescriptor.Author);
     
    if(Uri.IsWellFormedUriString(extensionDescriptor.WebSite, UriKind.Absolute)) {
    context.Builder.ProjectUrl = new Uri(extensionDescriptor.WebSite);
    }
    }
     
    private static void EmbedProjectFiles(CreateContext context, params string[] itemGroupTypes) {
    IEnumerable<XElement> itemGroups = context.Project
    .Elements(Ns("Project"))
    .Elements(Ns("ItemGroup"));
     
    foreach (string itemGroupType in itemGroupTypes) {
    IEnumerable<string> includePaths = itemGroups
    .Elements(Ns(itemGroupType))
    .Attributes("Include")
    .Select(x => x.Value);
    foreach (string includePath in includePaths) {
    EmbedVirtualFile(context, includePath, MediaTypeNames.Application.Octet);
    }
    }
    }
     
    private void EmbedReferenceFiles(CreateContext context) {
    var entries = context.Project
    .Elements(Ns("Project"))
    .Elements(Ns("ItemGroup"))
    .Elements(Ns("Reference"))
    .Select(reference => new {
    Include = reference.Attribute("Include"),
    HintPath = reference.Element(Ns("HintPath"))
    })
    .Where(entry => entry.Include != null);
     
    foreach (var entry in entries) {
    var assemblyName = new AssemblyName(entry.Include.Value);
     
    // If it is not a core assembly
    if (_frameworkAssemblies.GetFrameworkAssemblies().FirstOrDefault(assembly => assembly.Name.Equals(assemblyName.Name)) == null) {
    string virtualPath = _virtualPathProvider.GetReferenceVirtualPath(context.SourcePath, assemblyName.Name, entry.HintPath != null ? entry.HintPath.Value : null);
     
    if (!string.IsNullOrEmpty(virtualPath)) {
    EmbedVirtualFile(context, virtualPath, MediaTypeNames.Application.Octet);
    }
    }
    }
    }
     
    private static void EmbedThemeFiles(CreateContext context) {
    var basePath = context.SourcePath;
    foreach (var virtualPath in context.SourceFolder.ListFiles(context.SourcePath, true)) {
    // ignore dlls, etc
    if (IgnoreFile(virtualPath)) {
    continue;
    }
    // full virtual path given but we need the relative path so it can be put into
    // the package that way (the package itself is the logical base path).
    // Get it by stripping the basePath off including the slash.
    var relativePath = virtualPath.Replace(basePath, "");
    EmbedVirtualFile(context, relativePath, MediaTypeNames.Application.Octet);
    }
    }
     
    private static XName Ns(string localName) {
    return XName.Get(localName, "http://schemas.microsoft.com/developer/msbuild/2003");
    }
     
     
    private static void BeginPackage(CreateContext context) {
    context.Stream = new MemoryStream();
    context.Builder = new NuGetPackageBuilder();
    }
     
    private static void EstablishPaths(CreateContext context, IWebSiteFolder webSiteFolder, string locationPath, string moduleName, string moduleType) {
    context.SourceFolder = webSiteFolder;
    if (DefaultExtensionTypes.IsTheme(moduleType)) {
    context.SourcePath = "~/Themes/" + moduleName + "/";
    context.TargetPath = "\Content\Themes\" + moduleName + "\";
    }
    else {
    context.SourcePath = "~/Modules/" + moduleName + "/";
    context.TargetPath = "\Content\Modules\" + moduleName + "\";
    }
    }
     
    private static bool LoadProject(CreateContext context, string relativePath) {
    string virtualPath = context.SourcePath + relativePath;
    if (context.SourceFolder.FileExists(virtualPath)) {
    context.Project = XDocument.Parse(context.SourceFolder.ReadFile(context.SourcePath + relativePath));
    return true;
    }
    return false;
    }
     
    private static void EmbedVirtualFile(CreateContext context, string relativePath, string contentType) {
    var file = new VirtualPackageFile(
    context.SourceFolder,
    context.SourcePath + relativePath,
    context.TargetPath + relativePath);
    context.Builder.Files.Add(file);
    }
     
    private static void EndPackage(CreateContext context) {
    context.Builder.Save(context.Stream);
    }
     
    #region Nested type: CreateContext
     
    private class CreateContext {
    public Stream Stream { get; set; }
    public NuGetPackageBuilder Builder { get; set; }
     
    public IWebSiteFolder SourceFolder { get; set; }
    public string SourcePath { get; set; }
    public string TargetPath { get; set; }
     
    public XDocument Project { get; set; }
    }
     
    #endregion
     
    #region Nested type: CreateContext
     
    private class VirtualPackageFile : IPackageFile {
    private readonly IWebSiteFolder _webSiteFolder;
    private readonly string _virtualPath;
    private readonly string _packagePath;
     
    public VirtualPackageFile(IWebSiteFolder webSiteFolder, string virtualPath, string packagePath) {
    _webSiteFolder = webSiteFolder;
    _virtualPath = virtualPath;
    _packagePath = packagePath;
    }
     
    public string Path { get { return _packagePath; } }
     
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Supposed to return an open stream.")]
    public Stream GetStream() {
    var stream = new MemoryStream();
    _webSiteFolder.CopyFileTo(_virtualPath, stream);
    stream.Seek(0, SeekOrigin.Begin);
    return stream;
    }
    }
     
    #endregion
    }
    view rawgistfile1.cs hosted with ❤ by GitHub

    如果你是使用Orchard源码,那么你直接把上面的类覆盖到你的PackageBuilder类即可(一会儿会说明如何使用模块管理功能来更新打包功能)。

    image 

    编译后就可以享受不带源码的模块打包啦。

    如果你的项目中直接用的Orchard.Web,没有使用源码编译,那么没关系,你只需要到下面的地址下载dll,替换到你的modules文件夹下的Orchard.Package的bin中的Orchard.Package.dll即可。

    https://github.com/nicholaspei/Orchard.PackageAssembly/blob/master/assembly/Orchard.Packaging.zip

  • 相关阅读:
    分享一个文件的工具类
    关于itext生成pdf的新的demo(包含简单的提取txt文件的内容 和xml内容转化为pdf)
    全文检索的Demo
    dom4j操作xml的demo
    利用Java获取ip地址
    利用htmlparser读取html文档的内容
    关于pdfbox操作pdf的分享链接手长
    poi读取word的内容
    基于NPOI对Excel进行简单的操作
    “尝试加载 Oracle 客户端库时引发 BadImageFormatException。如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题。”
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3413337.html
Copyright © 2011-2022 走看看