What I'm trying to do, ultimately, is access the CacheSettingsPart so that I can programmatically add some ignored URLs to the output caching config.
The relevant admin controller already achieves this with:
var settings = Services.WorkContext.CurrentSite.As<CacheSettingsPart>();
settings.IgnoredUrls = model.IgnoredUrls;
I need something similar for my own method, but when I try and inject IOrchardServices, the WorkContext is null, meaning I don't have access to the CurrentSite.
I need suggestions of achieving this with an alternative approach or, ideally, a way of accessing the CurrentSite/CacheSettingsPart for me to amend the IgnoredUrls.
EDIT
var query = Services.ContentManager.Query<CacheSettingsPart>();
var cacheSettingsPart = query.List().First();
The above seems to be giving me what I need, I'll now test whether amending IgnoredUrls persists or not.
The WorkContext, as far as I can see, hasn't been created at the point of the Migration being run.
You could get the first SettingsPart as you suggest - it's probably not used for anything except the current site, though if you had multiple tenants, then I think you might run into trouble.
An alternative would be to inject ISiteService into your migrations class.
You can then do
var site = _siteService.GetSiteSettings();
var cacheSettings = site.As<CacheSettingsPart>();
var query = Services.ContentManager.Query<CacheSettingsPart>();
var cacheSettingsParts = query.Slice(1);
if(cacheSettingsParts.Any())
{
_signals.Trigger(CacheSettingsPart.CacheKey);
cacheSettingsParts.First().IgnoredUrls = "/dans-test";
}
The above works, but I appreciate it might not be the best approach so I'm open to other suggestions.
Related
I am new to NLog, but I think I have got a good understand of how it works in the last hours.
After digging deeper into NLog API, several questions about Logging Rules come up. One of them is:
How can I remove a rule by name (using LoggingConfiguration.RemoveRuleByName()) that I have added programmatically by LoggingConfiguration.AddRule() before?
LoggingConfiguration.AddRule() does not provide an argument to set the LoggingRule.RuleName.
LoggingConfiguration.AddRule() does not take a LoggingRule object.
I don't want to check every rule in the LoggingConfiguration.LoggingRules collection, because this would mean checking them by content, because I cannot set a name.
While writing the question, I found the solution, which I want to share here.
The LoggingConfiguration.LoggingRules collection is a IList<LoggingRule> and thus supports Add(), Clear(), etc.
Therefore it is possible to add LoggingRule objects directly into this list. The LoggingRule object can be removed again by IList<>.Remove(), and, if it has a name, by LoggingConfiguration.Remove().
Example for adding named rule:
var loggingRule1 = new NLog.Config.LoggingRule ();
loggingRule1.RuleName = nameof (loggingRule1); // RuleName can also be set in constructor.
loggingRule1.LoggerNamePattern = "*";
loggingRule1.SetLoggingLevels (NLog.LogLevel.Info, NLog.LogLevel.Error);
loggingRule1.Targets.Add (consoleTarget);
loggingConfiguration.LoggingRules.Add (loggingRule1);
var loggingRule2 = new NLog.Config.LoggingRule ("*", NLog.LogLevel.Trace, NLog.LogLevel.Trace, consoleTarget) { RuleName = "loggingRule2" };
loggingConfiguration.LoggingRules.Add (loggingRule2);
logFactory.ReconfigExistingLoggers ();
// or, if config was not yet set to logFactory: logFactory.Configuration = loggingConfiguration;
Example for removing named rule:
loggingConfiguration.RemoveRuleByName (nameof (loggingRule1));
logFactory.ReconfigExistingLoggers ();
IMHO the API is poorly documented. I will suggest some more comprehensive descriptions.
I have added a custom environment variable and I'm unable to get it to return in the ExpandEnvironmentVariables.
These 2 calls work fine:
string s = Environment.GetEnvironmentVariable("TEST", EnvironmentVariableTarget.Machine);
// s = "D:\Temp2"
string path = Environment.ExpandEnvironmentVariables(#"%windir%\Temp1");
// path = "C:\Windows\Temp1"
However, this call returns the same input string:
var path = Environment.ExpandEnvironmentVariables(#"%TEST%\Temp1");
// path = "%TEST%\\Temp1"
I expect to get D:\Temp2\Temp1
What am I missing to correctly get the custom EnvironmentVariable in this last call?
Hans and Evk were correct in their comments. Since no one wanted to add an answer I'll close this question out.
For whatever reason ExpandEnvironmentVariables will not get any keys which were added after an application started. I also tested this with a running Windows Service. It was only after I restarted the service that new keys were found and populated.
This behavior is not documented in the Microsoft Documentation.
My documentation and Google-fu is seriously failing me on this one, so:
how do I use P4API's GetChangelist() function to sync a range of files (i.e. all files from #now to #twoDaysAgo)? I can easily construct the command line to do this like so:
p4 changes -s submitted //...#2016/12/01,2016/12/06
but the API wants me to interface with the server via
GetChangelist(Options options, FileSpec[] files)
It's driving me crazy that I have to construct a combo of Options and Filespecs[] to make the request instead, and (AFAIK) can't just pass the actual command line string. Especially because all documentation seems to be non-existent.
Can somebody enlighten me as to what kind of filespec parameters I have to pass along? (I think that's what I need to use to specify the fact that I want to get a range of all CLs inside a certain time?) Thanks!
(As an aside: I was surprised there isn't a "P4API" tag yet, and I can't create one.)
And here's the non-command line version that you really want to use, from the Perforce documentation (once you find it :))
PathSpec path = new DepotPath("//depot/...");
DateTimeVersion lowerTimeStamp = new DateTimeVersion(new DateTime(2016,12,06));
DateTimeVersion upperTimeStamp = new DateTimeVersion(DateTime.Now);
VersionSpec version = new VersionRange(lowerTimeStamp, upperTimeStamp);
FileSpec[] fileSpecs = { new FileSpec(path, version) };
ChangesCmdOptions changeListOptions = new ChangesCmdOptions(ChangesCmdFlags.FullDescription | ChangesCmdFlags.IncludeTime, null, 0, ChangeListStatus.None, null);
IList<Changelist> changes = m_Repository.GetChangelists(changeListOptions, fileSpecs);
Alright, after a couple more hours of digging, I have found that there is a way to feed the actual command line parameters to the command. You create a DepotSpec, and then something like this is working for me to restrict the time range for CLs retrieved from the server:
ChangesCmdOptions changeListOptions = new ChangesCmdOptions(ChangesCmdFlags.FullDescription|ChangesCmdFlags.IncludeTime, null, 0, ChangeListStatus.None, null);
FileSpec[] fileSpecs = new FileSpec[1] { new FileSpec(new DepotPath("//depot/...#2016/12/05 21:57:30,#now"), null, null, null) };
IList<Changelist> changes = m_Repository.GetChangelists(changeListOptions, fileSpecs);
All this might be "indulgent smile" old news to people who've worked with the API for a while. It's just all a bit confusing to newcomers when documentation like the two pages mentioned in this post ("FileSpec object docs", "SyncFiles method docs") are offline now: Perforce Api - How to command "get revision [changelist number]"
I want to trigger a build from C#
In the build I need to change the default BuildController. My code look like this:
IBuildRequest buildRequest = BuildDefinition.CreateBuildRequest();
if(changebuildcontroller)
{
buildRequest.DropLocation = #"\\zzz.Domain.com\yyy$\TFS\Drop";
buildRequest.BuildController = **???**;
}
...
var queuedBuild = buildServer.QueueBuild(buildRequest);
Questions:
I would like to know how to find a list of buildcontrollers.
Any advice about how to understand the TFS object model will be appreciated. I looked at MSDN articles like this, but I do not see how it should help me. I used Google to find implementations of other objects in the Microsoft.TeamFoundation.Build.Client namespace.
It helped looking at another assignment for a while :)
If anyone else run into the same problem Use the Ibuildserver object to get a list of IBuildController
buildServer = (IBuildServer)teamProjectCollection.GetService(typeof(IBuildServer));
IBuildController[] buildserverlist = buildServer.QueryBuildControllers();
I'm having some trouble understanding and getting the search contract to work in my Store app. I have been unable to find any sort of documentation or guide that explains the structure of using the contract. (I've looked at the quickstarts on MSDN, the Search Contract sample and the build video, but that only really deals with javascript)
So far I've been able to run a query and get a list (of Custom Objects) into my search contract page, and from there I try to assign that to defaultviewmodel.results, but no matter what query I type nothing shows up I on the page. Is there something else I need to set?
What I have so far is as follows (excerpts):
App.xaml.cs
protected override void OnSearchActivated(Windows.ApplicationModel.Activation.SearchActivatedEventArgs args)
{
SearchCharmResultsPage.Activate(args.QueryText, args.PreviousExecutionState);
SearchCharmResultsPage.ProcessSearchQuery(args.QueryText);
}
public async static void ProcessSearchQuery(string queryString)
{
try
{
StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync("recipeCustomObject Debug.WriteLine("Database exists, connecting");
SQLiteAsyncConnection connection = new SQLiteAsyncConnection("CustomObject_db");
List<CustomObject> resultsList = new List<CustomObject>();
string query = "SELECT * FROM CustomObjectDB";
resultsList = await connection.QueryAsync<RecipeRecord>(query);
}
catch (FileNotFoundException fnfExc)
{
Debug.WriteLine("FNFEXC: " + fnfExc.ToString());
}
}
I think it is possible that here lies the problem, though I'm not sure if it is, or how to change it.
the resultsList list is created here, but because the method it asynchronous, I can't return from the method. Because of this I'm guess that when I try to assign this.DefaultViewModel[Results] = resultsList; in the LoadStateMethod, the object doesn't exist (thought the program throws no error). When I try to add the same line in the ProcessSearchQuery method, i'm told that this is not valid in a static method, but I think I need the method to be static? My problem might just be a fundamental logic error?
Finally got it! found the solution here: http://jeffblankenburg.com/2012/11/06/31-days-of-windows-8-day-6-search-contract
For those looking for an answer in the future, the key is to make sure you have your search logic within the Filter_SelectionChanged method, which was something I wasn't doing. Look at the guide within the above link to get an idea of the structure.
Have you looked at the Search contract sample on the developer center? There's a C#/XAML version there as well.
My open source Win8 RSS Reader framework implements Search (and Share) have a look at the source and if you still got questions, I'll be happy to help http://win8rssreader.codeplex.com/