MEF - List of DLLs to load - mef

We have many products that will share common DLLs. For a product, I would like to indicate a specific list of DLLs to include in the catalog. I know I can do this:
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(typeof(MainWindow).Assembly));
string fullPath = Path.Combine(#"D:\Folder\With\Plugins", "SomePlugin.dll");
Assembly dll = Assembly.LoadFile(fullPath);
ComposablePartCatalog assemblyCatalog = new AssemblyCatalog(dll);
catalog.Catalogs.Add(assemblyCatalog);
_container = new CompositionContainer(catalog);
_container.ComposeParts(this);
Would looping in the middle part for each specific file be the best method?

MEF provides a DirectoryCatalog. All you have to do is point the directory that contains the plugins and it will handle the rest, no loop necessary. Something like this:
string fullPath = Path.Combine(#"D:\Folder\With\Plugins");
var catalog = new DirectoryCatalog(fullPath);
_container = new CompositionContainer(catalog);
_container.ComposeParts(this);

Related

how to create node path similar to the sling job creates

AEM6.2 - I want to create a node hierarchy similar to the sling creates under "/var/eventing/..".
It should be based as "var/eventing/xx/year/month/date/hours/minutes/seconds/milisenconds/<>"
How do you suggest - to create each folder node by iterating the date format "YYYY/MM/dd/hh/mm/ss/SSS" ?
Or is there any other best way ?
You can use ResourceUtil.getOrCreateResource method. Pass the complete path you need and it will create all the sub directories if it does not already exist
String VAR_DATA_ROOT = "/var/eventing";
Date currentDate = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("/YYYY/MM/dd/hh/mm/ss/SSS");
String bucketPath = VAR_DATA_ROOT+simpleDateFormat.format(currentDate);
Resource bucketResource = ResourceUtil.getOrCreateResource(resourceResolver,bucketPath,null,null,false);
//save the data under bucketResource
resourceResolver.commit();

VSTS Create Area Path with WorkItemClassificationNode

I'm using the VSTS .NET client libraries and I'm trying to create an area path. I already have a WorkItemTrackingHttpClient. On this client I can create an area path with the CreateOrUpdateClassificationNodeAsync Method. But I can't set the parent of the area path.
var node = new WorkItemClassificationNode();
node.StructureType = TreeNodeStructureType.Area;
node.Name = "Test";
var result = await this.Client.CreateOrUpdateClassificationNodeAsync(node, "Team-Project", TreeStructureGroup.Areas);
How can I set the parent of the area path?
You almost got it right. To create a area at a certain path, use the following code:
var node = new WorkItemClassificationNode();
node.StructureType = TreeNodeStructureType.Area;
node.Name = “Name”;
var result = this.Client.CreateOrUpdateClassificationNodeAsync(
node,
"Project",
TreeStructureGroup.Areas,
"Path/to/parent/node/");
The important parameter is the path specifying the parent of the new node.
Shai has a create set of articles on the TFS SDK. This article shows how you can interact with classification nodes: http://blogs.microsoft.co.il/shair/2009/01/30/tfs-api-part-10-add-areaiteration-programmatically/

Create a shared folder in Dropbox with dropbox-core-sdk-2.0-beta-4 and then add a member to it

I am trying to create a shared folder in a dropbox account, from a Java desktop application by using the dropbox-core-sdk-2.0-beta-4, with the code below, but I am getting these exceptions:
java.lang.NoSuchMethodError: com.dropbox.core.json.JsonWriter.writeFields(Ljava/lang/Object;Lcom/fasterxml/jack son/core/JsonGenerator;)V
at com.dropbox.core.v2.DbxFiles$CreateFolderArg$1.write(DbxFiles.java:5337)
at com.dropbox.core.v2.DbxFiles$CreateFolderArg$1.write(DbxFiles.java:5332)
at com.dropbox.core.json.JsonWriter.writeToStream(JsonWriter.java:23)
at com.dropbox.core.json.JsonWriter.writeToStream(JsonWriter.java:33)
at com.dropbox.core.v2.DbxRawClientV2.rpcStyle(DbxRawClientV2.java:82)
at com.dropbox.core.v2.DbxFiles.createFolder(DbxFiles.java:8459)
at com.dropbox.core.v2.DbxFiles.createFolder(DbxFiles.java:8479)
My code is the following:
DbxRequestConfig dbxRequestConfig = new DbxRequestConfig("test/1.0", Locale.getDefault().toString());
DbxClientV2 dbxClient = new DbxClientV2(dbxRequestConfig, my_access_token);
FolderMetadata md = dbxClient.files.createFolder("/test");
ArrayList<AddMember> list = new ArrayList();
DbxSharing.AddMember a1 = new DbxSharing.AddMember(DbxSharing.MemberSelector.email("xxxxxx#gmail.com"),
DbxSharing.AccessLevel.editor);
list.add(a1);
dbxClient.sharing.addFolderMember(md.parentSharedFolderId, list);
My code is heating at:
FolderMetadata md = dbxClient.files.createFolder("/test");
I have already search for any solution to create a shared folder and add a member to it, but I am not finding anything useful to my case.
Could anyone tell me what I am doing wrong?

Enterprise Library Fluent API and Rolling Log Files Not Rolling

I am using the Fluent API to handle various configuration options for Logging using EntLib.
I am building up the loggingConfiguration section manually in code. It seems to work great except that the RollingFlatFileTraceListener doesn't actually Roll the file. It will respect the size limit and cap the amount of data it writes to the file appropriately, but it doesn't not actually create a new file and continue the logs.
I've tested it with a sample app and the app.config and it seems to work. So I'm guess that I am missing something although every config option that seems like it needs is there.
Here is the basics of the code (with hard-coded values to show a config that doesn't seem to be working):
//Create the config builder for the Fluent API
var configBuilder = new ConfigurationSourceBuilder();
//Start building the logging config section
var logginConfigurationSection = new LoggingSettings("loggingConfiguration", true, "General");
logginConfigurationSection.RevertImpersonation = false;
var _rollingFileListener = new RollingFlatFileTraceListenerData("Rolling Flat File Trace Listener", "C:\\tracelog.log", "----------------------", "",
10, "MM/dd/yyyy", RollFileExistsBehavior.Increment,
RollInterval.Day, TraceOptions.None,
"Text Formatter", SourceLevels.All);
_rollingFileListener.MaxArchivedFiles = 2;
//Add trace listener to current config
logginConfigurationSection.TraceListeners.Add(_rollingFileListener);
//Configure the category source section of config for flat file
var _rollingFileCategorySource = new TraceSourceData("General", SourceLevels.All);
//Must be named exactly the same as the flat file trace listener above.
_rollingFileCategorySource.TraceListeners.Add(new TraceListenerReferenceData("Rolling Flat File Trace Listener"));
//Add category source information to current config
logginConfigurationSection.TraceSources.Add(_rollingFileCategorySource);
//Add the loggingConfiguration section to the config.
configBuilder.AddSection("loggingConfiguration", logginConfigurationSection);
//Required code to update the EntLib Configuration with settings set above.
var configSource = new DictionaryConfigurationSource();
configBuilder.UpdateConfigurationWithReplace(configSource);
//Set the Enterprise Library Container for the inner workings of EntLib to use when logging
EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer(configSource);
Any help would be appreciated!
Your timestamp pattern is wrong. It should be yyy-mm-dd instead of MM/dd/yyyy. The ‘/’ character is not supported.
Also, you could accomplish your objective by using the fluent configuration interface much easier. Here's how:
ConfigurationSourceBuilder formatBuilder = new ConfigurationSourceBuilder();
ConfigurationSourceBuilder builder = new ConfigurationSourceBuilder();
builder.ConfigureLogging().LogToCategoryNamed("General").
SendTo.
RollingFile("Rolling Flat File Trace Listener")
.CleanUpArchivedFilesWhenMoreThan(2).WhenRollFileExists(RollFileExistsBehavior.Increment)
.WithTraceOptions(TraceOptions.None)
.RollEvery(RollInterval.Minute)
.RollAfterSize(10)
.UseTimeStampPattern("yyyy-MM-dd")
.ToFile("C:\\logs\\Trace.log")
.FormatWith(new FormatterBuilder().TextFormatterNamed("textFormatter"));
var configSource = new DictionaryConfigurationSource();
builder.UpdateConfigurationWithReplace(configSource);
EnterpriseLibraryContainer.Current = EnterpriseLibraryContainer.CreateDefaultContainer(configSource);
var writer = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
DateTime stopWritingTime = DateTime.Now.AddMinutes(10);
while (DateTime.Now < stopWritingTime)
{
writer.Write("test", "General");
}

How to OpenWebConfiguration with physical path?

I have a win form that creates a site in IIS7.
One function needs to open the web.config file and make a few updates. (connection string, smtp, impersonation)
However I do not have the virtual path, just the physical path.
Is there any way I can still use WebConfigurationManager?
I need to use it's ability to find section and read/write.
System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration
You will have to map the physicalPath to a virtualPath. Here is how you would do that.
using System.Web.Configuration; //Reference the System.Web DLL (project needs to be using .Net 4.0 full, not client framework)
public static Configuration OpenConfigFile(string configPath)
{
var configFile = new FileInfo(configPath);
var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/");
}
Vadim's answer worked great on our dev server, but bombed out on our live server with the following message:
System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: site
To correct this, I found another overload for WebConfigurationManager.OpenMappedWebConfiguration that takes the IIS website name as the third parameter. The result is as follows:
public static Configuration OpenConfigFile(string configPath)
{
var configFile = new FileInfo(configPath);
var vdm = new VirtualDirectoryMapping(configFile.DirectoryName, true, configFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/", "iis_website_name");
}
Vadim's answer was exactly what I needed, but I came across the same issue as Kieth, and his solution did the trick!
I thought I'd add though, that the IIS Website name can be retrieved by calling:
System.Web.Hosting.HostingEnvironment.ApplicationHost.GetSiteName();
Also, cjbarth's code included a tidy solution for those testing in environments where the location of wwwroot and Web.config can vary:
System.Web.HttpContext.Current.Server.MapPath("~");
So with these in mind another slight improvement on Vadim's function would read:
public static Configuration GetWebConfig() {
var webConfigFile = new FileInfo("Web.config");
var wwwRootPath = HttpContext.Current.Server.MapPath("~");
var vdm = new VirtualDirectoryMapping(wwwRootPath, true, webConfigFile.Name);
var wcfm = new WebConfigurationFileMap();
wcfm.VirtualDirectories.Add("/", vdm);
var siteName = HostingEnvironment.ApplicationHost.GetSiteName();
return WebConfigurationManager.OpenMappedWebConfiguration(wcfm, "/", siteName);
}
I ended up using Powershell.
$file = "D:\Applications\XXX\Private\XXX\XXXX\web.config"
$configurationAssembly = "System.Configuration, Version=4.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a"
[Void] [Reflection.Assembly]::Load($configurationAssembly)
$filepath = New-Object System.Configuration.ExeConfigurationFileMap
$filepath.ExeConfigFileName = $file
$configuration = [System.Configuration.ConfigurationManager]::OpenMappedExeConfiguration($filepath,0)
$section = $configuration.GetSection("appSettings")
Write-Host "Set the Protection Provider"
if (-not $section.SectionInformation.IsProtected)
{
$section.SectionInformation.ProtectSection("DataProtectionConfigurationProvider")
$configuration.Save()
}
Building on Vadim's answer, I found what he wrote didn't exactly work for my situation, so I used this instead:
Dim connectionSettings As New ConnectionStringSettings("mySQLite", ConnectionStringHelper.MyConnectionString)
Dim dummyVirtualPath As String = "/MyApp"
Dim virtualDirMap = New VirtualDirectoryMapping(Server.MapPath("~"), True)
Dim webConfigFileMap = New WebConfigurationFileMap()
webConfigFileMap.VirtualDirectories.Add(dummyVirtualPath, virtualDirMap)
Dim mappedConfigFile = WebConfigurationManager.OpenMappedWebConfiguration(webConfigFileMap, dummyVirtualPath)
Dim config As System.Configuration.Configuration = mappedConfigFile WebConfigurationManager.OpenWebConfiguration(Server.MapPath("~") & "/")
Dim csSection As ConnectionStringsSection = config.ConnectionStrings
If csSection.ConnectionStrings("mySQLite") IsNot Nothing AndAlso csSection.ConnectionStrings("mySQLite").ConnectionString <> connectionSettings.ConnectionString Then
csSection.ConnectionStrings("mySQLite").ConnectionString = connectionSettings.ConnectionString
config.Save()
ConfigurationManager.RefreshSection(csSection.SectionInformation.Name)
End If
In case anyone else is trying what I'm trying and finds this, the purpose of my doing this was to get SimpleMembershipProvider, which inherits from ExtendedMembershipProvider, to work with SQLite. To do that, I created the tables manually per this link: SimpleMembershipProvider in MVC4, and then used this command in my Global.asax file's Application_Start routine:
WebSecurity.InitializeDatabaseConnection(ConnectionStringHelper.MyConnectionString, "System.Data.SQLite", "Users", "UserID", "Email", False)
Which it turns out didn't require me to actually re-write my web.config file at all. (There were also a lot of web.config changes I had to do, but that is even more out of the scope of this question.)