Xtensive.Sql.All assembly referencing all of them (btw, I really did this in our repository). Actually, this assembly contains a single type, which will never be instantiated:
As you see, this type references types from all SQL DOM assemblies (including its providers). This is necessary, because otherwise C# complier will not add references to these assemblies to Xtensive.Sql.All.dll, even although the project it is built by includes them.
So practically you can't use this type. But it makes C# compiler to list all the references we need Xtensive.Sql.All.dll assembly: Note that each of these assemblies also needs many others. For example, let's take a look at Xtensive.Sql.PostgreSql.dll assembly there. It references Npgsql.dll, which in turn references Mono.Security.dll.
So now you understand the problem. I'd like all these assemblies to be in bin folder of my application automatically. I don't want to manually discover all the dependencies and write a code like this to copy them:
Case 2. The same is about our Xtensive.Storage providers and assemblies. So I created Xtensive.Storage.All assembly referencing all you might need. This assembly contains very similar Referencer type.
Let's go to the solution now.
Solution: CopyIndirectDependencies.targets.
Here it is:
Its intended usage: add a single highlighted line importing this file to any .csproj / .vbproj.
Check out demo application using this .target:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/// <summary>/// Does nothing, but references types from all SQL DOM assemblies./// </summary>public sealed class Referencer
{ private Type[] types = new [] {
typeof (Pair<>),
typeof (SqlType),
typeof (SqlServer.DriverFactory),
typeof (PostgreSql.DriverFactory),
typeof (Oracle.DriverFactory),
typeof (VistaDb.DriverFactory),
};
// This is the only constructor. So you can't instantiate this type.
private Referencer()
{
}
} |
So practically you can't use this type. But it makes C# compiler to list all the references we need Xtensive.Sql.All.dll assembly: Note that each of these assemblies also needs many others. For example, let's take a look at Xtensive.Sql.PostgreSql.dll assembly there. It references Npgsql.dll, which in turn references Mono.Security.dll.
So now you understand the problem. I'd like all these assemblies to be in bin folder of my application automatically. I don't want to manually discover all the dependencies and write a code like this to copy them:
|
1
2
3
4
5
6
|
<Target Name="AfterBuild" DependsOnTargets="RequiresPostSharp">
<CreateItem Include="$(SolutionDir)\Lib\*.*">
<Output TaskParameter="Include" ItemName="CopyFiles" />
</CreateItem>
<Copy SourceFiles="@(CopyFiles)" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
</Target>
|
Let's go to the solution now.
Solution: CopyIndirectDependencies.targets.
Here it is:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
<?xml version="1.0" encoding="utf-8"?>
<PropertyGroup>
<CopyIndirectDependencies Condition="'$(CopyIndirectDependencies)'==''">true</CopyIndirectDependencies>
<CopyIndirectDependenciesPdb
Condition="'$(CopyIndirectDependenciesPdb)'==''">false</CopyIndirectDependenciesPdb>
<CopyIndirectDependenciesXml
Condition="'$(CopyIndirectDependenciesXml)'==''">false</CopyIndirectDependenciesXml>
</PropertyGroup>
<!-- BuildXxx part -->
<Target Name="CopyIndirectDependencies"
Condition="'$(CopyIndirectDependencies)'=='true'"
DependsOnTargets="DetectIndirectDependencies">
<Copy Condition="'%(IndirectDependency.FullPath)'!=''"
SourceFiles="%(IndirectDependency.FullPath)"
DestinationFolder="$(OutputPath)"
SkipUnchangedFiles="true" >
<Output TaskParameter="CopiedFiles"
ItemName="IndirectDependencyCopied" />
</Copy>
<Message Importance="low"
Condition="'%(IndirectDependencyCopied.FullPath)'!=''
and '%(IndirectDependencyCopied.Extension)'!='.pdb'
and '%(IndirectDependencyCopied.Extension)'!='.xml'"
Text="Indirect dependency copied: %(IndirectDependencyCopied.FullPath)" />
</Target>
<Target Name="DetectIndirectDependencies"
DependsOnTargets="ResolveAssemblyReferences">
<Message Importance="low"
Text="Direct dependency: %(ReferencePath.Filename)%(ReferencePath.Extension)" />
<Message Importance="low"
Text="Indirect dependency: %(ReferenceDependencyPaths.Filename)%(ReferenceDependencyPaths.Extension)" />
<!-- Creating indirect dependency list -->
<CreateItem Include="%(ReferenceDependencyPaths.FullPath)"
Condition="'%(ReferenceDependencyPaths.CopyLocal)'=='true'">
<Output TaskParameter="Include"
ItemName="_IndirectDependency"/>
</CreateItem>
<CreateItem Include="%(ReferenceDependencyPaths.RootDir)%(ReferenceDependencyPaths.Directory)%(ReferenceDependencyPaths.Filename).xml"
Condition="'%(ReferenceDependencyPaths.CopyLocal)'=='true' and '$(CopyIndirectDependenciesXml)'=='true'">
<Output TaskParameter="Include"
ItemName="_IndirectDependency"/>
</CreateItem>
<CreateItem Include="%(ReferenceDependencyPaths.RootDir)%(ReferenceDependencyPaths.Directory)%(ReferenceDependencyPaths.Filename).pdb"
Condition="'%(ReferenceDependencyPaths.CopyLocal)'=='true' and '$(CopyIndirectDependenciesPdb)'=='true'">
<Output TaskParameter="Include"
ItemName="_IndirectDependency"/>
</CreateItem>
<!-- Filtering indirect dependency list by existence -->
<CreateItem Include="%(_IndirectDependency.FullPath)"
Condition="Exists('%(_IndirectDependency.FullPath)')">
<Output TaskParameter="Include"
ItemName="IndirectDependency"/>
</CreateItem>
<!-- Creating copied indirect dependency list -->
<CreateItem Include="@(_IndirectDependency->'$(OutputPath)%(Filename)%(Extension)')">
<Output TaskParameter="Include"
ItemName="_ExistingIndirectDependency"/>
</CreateItem>
<!-- Filtering copied indirect dependency list by existence -->
<CreateItem Include="%(_ExistingIndirectDependency.FullPath)"
Condition="Exists('%(_ExistingIndirectDependency.FullPath)')">
<Output TaskParameter="Include"
ItemName="ExistingIndirectDependency"/>
</CreateItem>
</Target>
<!-- Build sequence modification -->
<PropertyGroup>
<CoreBuildDependsOn>
$(CoreBuildDependsOn);
CopyIndirectDependencies
</CoreBuildDependsOn>
</PropertyGroup>
</Project>
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="CopyIndirectDependencies.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
|
- Download and extract it
- Open it in Visual Studio and build it there, or build it by typing "msbuild" (of course, if it is in your PATH)
- Check out "bin" folder. It already contains Mono.Security.dll from Lib folder, although application references just Npgsql.dll (it requires Mono.Security.dll).
If you'd like to suppress Visual Studio warning on opening such modified projects for the first time, see this article (in particular, "Non-standard Import Elements" section).
Update: initial version of CopyIndirectDependencies.targets published here was buggy, but now it's fixed.
Update: initial version of CopyIndirectDependencies.targets published here was buggy, but now it's fixed.
http://blog.alexyakunin.com/2009/09/making-msbuild-visual-studio-to.html