{"action":"created","issue":{"url":"https://api.github.com/repos/Microsoft/VSProjectSystem/issues/235","repository_url":"https://api.github.com/repos/Microsoft/VSProjectSystem","labels_url":"https://api.github.com/repos/Microsoft/VSProjectSystem/issues/235/labels{/name}","comments_url":"https://api.github.com/repos/Microsoft/VSProjectSystem/issues/235/comments","events_url":"https://api.github.com/repos/Microsoft/VSProjectSystem/issues/235/events","html_url":"https://github.com/Microsoft/VSProjectSystem/issues/235","id":240014194,"node_id":"MDU6SXNzdWUyNDAwMTQxOTQ=","number":235,"title":"Tyring to alter VCProject global properties doesn't cause the VCProject to evaluate build properties","user":{"login":"ceztko","id":3037449,"node_id":"MDQ6VXNlcjMwMzc0NDk=","avatar_url":"https://avatars2.githubusercontent.com/u/3037449?v=4","gravatar_id":"","url":"https://api.github.com/users/ceztko","html_url":"https://github.com/ceztko","followers_url":"https://api.github.com/users/ceztko/followers","following_url":"https://api.github.com/users/ceztko/following{/other_user}","gists_url":"https://api.github.com/users/ceztko/gists{/gist_id}","starred_url":"https://api.github.com/users/ceztko/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ceztko/subscriptions","organizations_url":"https://api.github.com/users/ceztko/orgs","repos_url":"https://api.github.com/users/ceztko/repos","events_url":"https://api.github.com/users/ceztko/events{/privacy}","received_events_url":"https://api.github.com/users/ceztko/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2017-07-02T14:41:36Z","updated_at":"2018-09-27T02:18:49Z","closed_at":null,"author_association":"NONE","body":"I'm developer of a [extension](https://github.com/ceztko/SolutionConfigurationName) for VS to add $(SolutionConfiguration) and $(SolutionPlatform) macros (the values that can be seen on the IDE combobox) to VS project settings.\r\nSince altering ProjectCollection is becoming less and less predictable, I am trying to follow the [documentation](https://github.com/Microsoft/VSProjectSystem/blob/master/doc/extensibility/IProjectGlobalPropertiesProvider.md) to define a `IProjectGlobalPropertiesProvider` MEF component that will plug this macros without accessing directly the MSBuild project or collection. This is my code:\r\n\r\n```cs\r\n    [Export(typeof(IProjectGlobalPropertiesProvider))]\r\n    [AppliesTo(\"VisualC + VCProjectEngineFactory\")] // Copied from internal VCGlobalPropertiesProvider\r\n    public class SolutionConfigurationPropertiesProvider :\r\n        ProjectValueDataSourceBase<IImmutableDictionary<string, string>>,\r\n        IProjectGlobalPropertiesProvider\r\n    {\r\n        const string NAME_IDENTITY = \"SolutionConfiguration\";\r\n\r\n        private static object _lock;\r\n        private static SolutionConfigurationPropertiesProvider _instance;   // Lock guarded\r\n        private static IImmutableDictionary<string, string> _properties;    // Lock guarded\r\n        private static IComparable _version;                                // Lock guarded\r\n        private static BroadcastBlock<IProjectVersionedValue<IImmutableDictionary<string, string>>> _brodcastBlock; // Lock guarded\r\n\r\n        private static IReceivableSourceBlock<IProjectVersionedValue<IImmutableDictionary<string, string>>> _publicBlock;\r\n        private static NamedIdentity _dataSourceKey;\r\n\r\n        static SolutionConfigurationPropertiesProvider()\r\n        {\r\n            _version = 0L;\r\n            _lock = new object();\r\n            _properties = ImmutableDictionary<string, string>.Empty;\r\n            _dataSourceKey = new NamedIdentity(NAME_IDENTITY);\r\n        }\r\n\r\n        // The scope is the solution ProjectCollection for VC projects\r\n        // https://github.com/Microsoft/VSProjectSystem/blob/master/doc/overview/scopes.md\r\n        [ImportingConstructor]\r\n        protected SolutionConfigurationPropertiesProvider(IProjectService service)\r\n            : base(service.Services)\r\n        {\r\n            lock (_lock)\r\n            {\r\n                _instance = this;\r\n            }\r\n        }\r\n\r\n        public static void SetSolutionConfiguration(string configurationName, string platformName)\r\n        {\r\n            lock (_lock)\r\n            {\r\n                _properties = GetDictionary(configurationName, platformName);\r\n\r\n                if (_instance != null)\r\n                    _instance.PostSolutionConfiguration();\r\n            }\r\n        }\r\n\r\n        private void PostSolutionConfiguration()\r\n        {\r\n            _version = (long)_version + 1;\r\n            postSolutionConfiguration();\r\n        }\r\n\r\n        private void postSolutionConfiguration()\r\n        {\r\n            _brodcastBlock.Post(\r\n                new ProjectVersionedValue<IImmutableDictionary<string, string>>(_properties,\r\n                    ImmutableDictionary<NamedIdentity, IComparable>.Empty.Add(_dataSourceKey, _version)));\r\n        }\r\n\r\n        public override NamedIdentity DataSourceKey => _dataSourceKey;\r\n\r\n        public override IComparable DataSourceVersion\r\n        {\r\n            get { lock (_lock) { return _version; } }\r\n        }\r\n\r\n        public override IReceivableSourceBlock<IProjectVersionedValue<IImmutableDictionary<string, string>>> SourceBlock\r\n        {\r\n            get\r\n            {\r\n                EnsureInitialized();\r\n                return _publicBlock;\r\n            }\r\n        }\r\n\r\n        public Task<IImmutableDictionary<string, string>> GetGlobalPropertiesAsync(CancellationToken cancellationToken)\r\n        {\r\n            lock (_lock)\r\n            {\r\n                return Task.FromResult(_properties);\r\n            }\r\n        }\r\n\r\n        static IImmutableDictionary<string, string> GetDictionary(string configurationName, string platformName)\r\n        {\r\n            var builder = Microsoft.VisualStudio.ProjectSystem.Empty.PropertiesMap.ToBuilder();\r\n            builder.Add(\"SolutionConfiguration\", configurationName);\r\n            builder.Add(\"SolutionPlatform\", platformName);\r\n            return builder.ToImmutable();\r\n        }\r\n\r\n        protected override void Initialize()\r\n        {\r\n            base.Initialize();\r\n\r\n            lock (_lock)\r\n            {\r\n                _brodcastBlock = new BroadcastBlock<IProjectVersionedValue<IImmutableDictionary<string, string>>>(null,\r\n                    new DataflowBlockOptions() { NameFormat = NAME_IDENTITY + \": {1}\" });\r\n                _publicBlock = _brodcastBlock.SafePublicize();\r\n\r\n                postSolutionConfiguration();\r\n            }\r\n        }\r\n    }\r\n```\r\n\r\n1) This is code is not working: the macros are correctly passed to the project settings GUI (I can see them in the macros editor) but are ignored during build. If I invalidate project settings with dummy modification, reverted immediately after, the build system is able to recognize the change in the properties and builds correctly. The versioning system that is in place seems to be correct to me, I also got inspiration from [here](https://github.com/Microsoft/VSProjectSystem/blob/master/doc/extensibility/dataflow_example.md);\r\n2) **EDIT: Answered**\r\nHow do I ensure the provider will be a singleton for all VCProject(s)? The imported constructor is called multiple times.\r\n\r\nNote: the capability I'm using, \"VisualC + VCProjectEngineFactory\", is taken from inspected VS code and seems to apply correctly to VCProject(s). Same problems happen if using the (supposedly) global capability \"\"."},"comment":{"url":"https://api.github.com/repos/Microsoft/VSProjectSystem/issues/comments/424934543","html_url":"https://github.com/Microsoft/VSProjectSystem/issues/235#issuecomment-424934543","issue_url":"https://api.github.com/repos/Microsoft/VSProjectSystem/issues/235","id":424934543,"node_id":"MDEyOklzc3VlQ29tbWVudDQyNDkzNDU0Mw==","user":{"login":"JunielKatarn","id":4507319,"node_id":"MDQ6VXNlcjQ1MDczMTk=","avatar_url":"https://avatars1.githubusercontent.com/u/4507319?v=4","gravatar_id":"","url":"https://api.github.com/users/JunielKatarn","html_url":"https://github.com/JunielKatarn","followers_url":"https://api.github.com/users/JunielKatarn/followers","following_url":"https://api.github.com/users/JunielKatarn/following{/other_user}","gists_url":"https://api.github.com/users/JunielKatarn/gists{/gist_id}","starred_url":"https://api.github.com/users/JunielKatarn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JunielKatarn/subscriptions","organizations_url":"https://api.github.com/users/JunielKatarn/orgs","repos_url":"https://api.github.com/users/JunielKatarn/repos","events_url":"https://api.github.com/users/JunielKatarn/events{/privacy}","received_events_url":"https://api.github.com/users/JunielKatarn/received_events","type":"User","site_admin":false},"created_at":"2018-09-27T02:18:49Z","updated_at":"2018-09-27T02:18:49Z","author_association":"NONE","body":"Hey @ceztko, sorry to post an unrelated question here, but, did you find a way to instantiate a `VCProjectEngine`, or ultimately a `VCProject`?\r\nI'm looking to write some tooling for VCXPROJ files, but can't find any documentation to get started."}}
{"actor":{"display_login":"JunielKatarn"}}