Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Ryios 122 posts 263 karma points
    Feb 17, 2015 @ 07:04
    Ryios
    0

    Use the Umbraco Services from a console app?

    Assuming I have the connection string, app settings, etc in a console apps app.config, how can I instantiate the Umbraco Context from another (non umbraco site).

    Basically I want to access the ContentService, DataTypeService, MediaTypeService, and MediaService in a console app (making some powershell cmd-lets).

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Feb 17, 2015 @ 07:37
    Jan Skovgaard
    1

    Hi Ryan

    Perhaps you can find the asnwer in Morten's post here https://our.umbraco.org/forum/developers/api-questions/37981-Using-v6-API-ContentService-in-external-application#comment141877 ? He links to a github repository where he is using the content service from a console app.

    Hope this helps.

    /Jan

  • Ryios 122 posts 263 karma points
    Feb 17, 2015 @ 08:41
    Ryios
    0

    Yeah, I figured it out with reflector. While I cannot instantiate the entire ApplicationContext (which makes sense)... I can instantiate each of the individual services with a few steps required.

    • Move (at a minimum) the following web.config stuff to your console app.Config
      1. appSettings -> umbracoConfigurationStatus (ex: 7.2.1)
      2. connectionStrings -> umbracoDbDSN (you can change the name, but change your IDatabaseFactory implementation to match)
      3. umbracoConfiguration/settings
      4. umbracoConfiguration/dashBoard
      5. umbracoConfiguration/BaseRestExtensions
    • Create a class that inherits from DisposableObject and IDatabaseFactory (code below)
    • Instantiate the services you want

    I used .Net Reflector to figure all of this out, straight up so let me know if anything will make this easier that exists in the umbraco code already (I don't want to use someones package/dependency, either OOTB umbraco, or build myself).

        public class UExternalDatabaseFactory : DisposableObject, IDatabaseFactory
        {
        [ThreadStatic]
        private static volatile UmbracoDatabase _nonHttpInstance;
        private static readonly object Locker;
    
        public string ConnectionString { get; private set; }
        public string ProviderName { get; private set; }
    
        static UGuruMetaSyncDatabaseFactory()
        {
            Locker = new object();
        }
        public UGuruMetaSyncDatabaseFactory()
            : this("umbracoDbDSN")
        {
        }
        public UGuruMetaSyncDatabaseFactory(string connectionStringName)
        {
            Mandate.ParameterNotNullOrEmpty(connectionStringName, "connectionStringName");
            this.ConnectionString = connectionStringName;
        }
        public UGuruMetaSyncDatabaseFactory(string connectionStringName, string providerName)
        {
            Mandate.ParameterNotNullOrEmpty(connectionStringName, "connectionStringName");
            Mandate.ParameterNotNullOrEmpty(providerName, "providerName");
            this.ConnectionString = connectionStringName;
            this.ProviderName = providerName;
        }
    
        public UmbracoDatabase CreateDatabase()
        {
            if (_nonHttpInstance == null)
            {
                lock (Locker)
                {
                    if (_nonHttpInstance == null)
                    {
                        _nonHttpInstance = (!string.IsNullOrEmpty(this.ConnectionString) && !string.IsNullOrEmpty(this.ProviderName)) ? new UmbracoDatabase(this.ConnectionString, this.ProviderName) : new UmbracoDatabase(this.ConnectionString);
                    }
                }
            }
            return _nonHttpInstance;
        }
        protected override void DisposeResources()
        {
            _nonHttpInstance.Dispose();
        }
    }
    

    Example Instantiation:

               var dbFactory = new UExternalDatabaseFactory();
            DatabaseContext dbContext = new DatabaseContext(dbFactory);
            //var umbracoSettings = UmbracoConfig.For.UmbracoSettings();
            var cacheHelper = new CacheHelper(); //this will do nothing, caching is disabled on the repository factory below, and HttpContext is null in this process.
            RepositoryFactory rFactory = new RepositoryFactory(true, cacheHelper);
            IContentService contentService = new ContentService(rFactory);
            IMediaService mediaService = new MediaService(rFactory);
            IContentTypeService contentTypeService = new ContentTypeService(rFactory, contentService, mediaService);
            IDataTypeService dataTypeService = new DataTypeService(rFactory);
            IFileService fileService = new FileService(rFactory);
            ILocalizationService localizationService = new LocalizationService(rFactory);
    
  • Ryios 122 posts 263 karma points
    Feb 17, 2015 @ 08:50
    Ryios
    1

    To add on to that. I came really close to initializing the entire ServiceContext object, but I ran into a brick wall with the ISectionService interface.

    For whatever reason, SectionService, ApplicationTreeService) are protected as internal, thus I cannot instantiate it without a reflection hack. So of the 15+(guessing) api's that I can instantiate, I cannot load ServiceContext up with them because I cannot instantiate 2 of them without implementing my own ISectionService and IApplicationTreeService objects. They use the same database context I am using for the other services, so for the life of me (reflection skills being strained) I cannot understand why those 2 classes are protected internal when 95% of what's needed is public.

    Was marking SectionService and ApplicationTreeService as internal a mistake? Doesn't make sense to me.

Please Sign in or register to post replies

Write your reply to:

Draft