Compare commits
164 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8fae55e44e | |||
| a8ca3a89bd | |||
| 765f959f20 | |||
| 2cf90477ed | |||
| 6ca6a08233 | |||
| 0119f1eb1b | |||
| cd4f66e7c5 | |||
| 3fdc0e5361 | |||
| 4bfb8569c8 | |||
| df9a887032 | |||
| 1e0a4690fc | |||
| 52163494db | |||
| 8416764a83 | |||
| 2d3eb8c208 | |||
| aa84a3f7f2 | |||
| 3594693f4b | |||
| c573459626 | |||
| b99de245bf | |||
| 222723b8fe | |||
| f758b33da5 | |||
| eeb0e0026a | |||
| 082dacf737 | |||
| afc2fd9420 | |||
| ff6715d42a | |||
| b776675ac8 | |||
| 1e21671b62 | |||
| 59184981cb | |||
| 0632ffb93d | |||
| 034aa6d8f9 | |||
| 1484fba1ad | |||
| 82fc1a5304 | |||
| f0aab6ae81 | |||
| 9ac325c1a4 | |||
| 8c257d39f9 | |||
| 76f040aef4 | |||
| 721f813d1e | |||
| 7ed5a6f706 | |||
| 35a698cdc9 | |||
| 6c9e82e735 | |||
| f7ddb1ed49 | |||
| c0fd974cc1 | |||
| e9c4a031c9 | |||
| 123e65c55f | |||
| e5e4e7b685 | |||
| 88795b86fd | |||
| 378a544c1a | |||
| a159b50c05 | |||
| 3891e46549 | |||
| e7bcc642a9 | |||
| 4983990d39 | |||
| e9a496df4f | |||
| 2f6dada481 | |||
| 580123cb87 | |||
| de0e47d7ef | |||
| ff5dc324fe | |||
| 096c5ad69f | |||
| eba7582a97 | |||
| 0cf2a1fc2a | |||
| 77ee87178e | |||
| a6997a5cb7 | |||
| ff3fc5d825 | |||
| 3b9bf7b0f9 | |||
| 3882e1984d | |||
| b32ea68fd0 | |||
| eb2db791b8 | |||
| 158f4d0614 | |||
| 7a38970cf4 | |||
| 7f6d8b6bdd | |||
| 22fb7e1706 | |||
| 12b1168de9 | |||
| 01290f8174 | |||
| 26a7bf8187 | |||
| ba1d0fa193 | |||
| 97355bde6f | |||
| ed35f234de | |||
| c874fa6507 | |||
| ba387598ed | |||
| 3ff1b01e46 | |||
| 36e803713c | |||
| a3e7f644de | |||
| 1586f1679a | |||
| 809badd1cf | |||
| da92ece774 | |||
| a531afb819 | |||
| 1d6009e3c7 | |||
| 8dfeb1e616 | |||
| 1b086e2267 | |||
| 1f86d8c562 | |||
| 25b9262cf1 | |||
| 1012a4814d | |||
| bae41cde14 | |||
| b3260f05c0 | |||
| e33a79ac65 | |||
| c4dbabf654 | |||
| 423643d66c | |||
| 4ccb655f73 | |||
| c8330d60f9 | |||
| a9aa3a04b5 | |||
| 0bffa8e3f4 | |||
| 436322f58c | |||
| e90c46dd78 | |||
| deda2534f8 | |||
| 8112c13857 | |||
| 57792de185 | |||
| e1f93029a5 | |||
| f64e0c7eb7 | |||
| bf024e9011 | |||
| 036b888d30 | |||
| 1838a8dac5 | |||
| 205bf5fe4e | |||
| a50e192ab7 | |||
| 9684255e6e | |||
| 72790d74f5 | |||
| bb70bee6ae | |||
| 0430e7966c | |||
| 2e9a52b1f8 | |||
| db4ed70d70 | |||
| e6ccd8a5b5 | |||
| a9781d79e2 | |||
| 7ae8b28466 | |||
| 29a4cb8b71 | |||
| ffb39de003 | |||
| 527375b238 | |||
| a4ed0e266c | |||
| 1929f60ea8 | |||
| b9cc2efc8c | |||
| eadb1bb194 | |||
| 30be665a40 | |||
| bad284515c | |||
| 5b660d95f1 | |||
| 106ac44e64 | |||
| 64bb7e1db0 | |||
| 25b9ca3b0e | |||
| b928170103 | |||
| e25ee246fb | |||
| 8e8ec41dae | |||
| fb34c4716a | |||
| 29bf61b1f2 | |||
| 9803309e34 | |||
| 3a539629dc | |||
| 74b970d586 | |||
| 518898b04b | |||
| a773e0a018 | |||
| 99fe89addc | |||
| 668d4f9f91 | |||
| 90e73cb89f | |||
| dcd6477030 | |||
| 13b73231de | |||
| 50a70c28df | |||
| 7d5589118f | |||
| c39b698d4c | |||
| 103efbdc27 | |||
| 3d51dd767b | |||
| e22988e435 | |||
| 9736aaafaa | |||
| bf3fa20a53 | |||
| f936f8b0dd | |||
| 1bd20c9b06 | |||
| 099b713947 | |||
| 165d9c7dff | |||
| 09400be6e0 | |||
| 7934ba7ec4 | |||
| 7edbc34e6c | |||
| 60b6608289 |
+2
-2
@@ -1,6 +1,6 @@
|
||||
@ECHO OFF
|
||||
SET release=6.1.0
|
||||
SET comment=beta
|
||||
SET release=6.0.4
|
||||
SET comment=
|
||||
SET version=%release%
|
||||
|
||||
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
|
||||
|
||||
+153
-193
@@ -1,19 +1,19 @@
|
||||
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
|
||||
<!--
|
||||
<!--
|
||||
****************************************************
|
||||
INCLUDES
|
||||
*****************************************************
|
||||
-->
|
||||
|
||||
<PropertyGroup>
|
||||
<MSBuildCommunityTasksPath>..\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
|
||||
<UmbracoMSBuildTasksPath>..\UmbracoMSBuildTasks</UmbracoMSBuildTasksPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\tools\UmbracoMSBuildTasks\Umbraco.MSBuild.Tasks.Targets" />
|
||||
<Import Project="..\tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
|
||||
<PropertyGroup>
|
||||
<MSBuildCommunityTasksPath>..\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
|
||||
<UmbracoMSBuildTasksPath>..\UmbracoMSBuildTasks</UmbracoMSBuildTasksPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\tools\UmbracoMSBuildTasks\Umbraco.MSBuild.Tasks.Targets" />
|
||||
<Import Project="..\tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" />
|
||||
|
||||
<UsingTask TaskName="GenerateHash" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
|
||||
<ParameterGroup>
|
||||
@@ -53,68 +53,65 @@
|
||||
</UsingTask>
|
||||
|
||||
|
||||
<!--
|
||||
<!--
|
||||
****************************************************
|
||||
VARIABLES
|
||||
*****************************************************
|
||||
-->
|
||||
|
||||
<!-- NB: BUILD_NUMBER is passed in by the build server -->
|
||||
<PropertyGroup Condition="'$(BUILD_NUMBER)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_NUMBER)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!='' AND '$(BUILD_COMMENT)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)-$(BUILD_COMMENT)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<!-- NB: BUILD_NUMBER is passed in by the build server -->
|
||||
<PropertyGroup Condition="'$(BUILD_NUMBER)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_NUMBER)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(BUILD_RELEASE)'!='' AND '$(BUILD_COMMENT)'!=''">
|
||||
<DECIMAL_BUILD_NUMBER>.$(BUILD_RELEASE)-$(BUILD_COMMENT)</DECIMAL_BUILD_NUMBER>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<BuildConfiguration>Release</BuildConfiguration>
|
||||
<BuildFolder>_BuildOutput\</BuildFolder>
|
||||
<BuildZipFileName>UmbracoCms$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileName>
|
||||
<BuildZipFileNameBin>UmbracoCms.AllBinaries$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameBin>
|
||||
<BuildZipFileNameWebPi>UmbracoCms.WebPI$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameWebPi>
|
||||
<IncludeSymbols>False</IncludeSymbols>
|
||||
<BuildFolderRelativeToProjects>..\..\build\$(BuildFolder)</BuildFolderRelativeToProjects>
|
||||
<BuildFolderAbsolutePath>$(MSBuildProjectDirectory)\$(BuildFolder)</BuildFolderAbsolutePath>
|
||||
<SolutionBinFolder>$(BuildFolder)bin\</SolutionBinFolder>
|
||||
<WebAppFolder>$(BuildFolder)WebApp\</WebAppFolder>
|
||||
<WebPiFolder>$(BuildFolder)WebPi\</WebPiFolder>
|
||||
<SolutionBinFolderRelativeToProjects>$(BuildFolderRelativeToProjects)bin\</SolutionBinFolderRelativeToProjects>
|
||||
<SolutionBinFolderAbsolutePath>$(BuildFolderAbsolutePath)bin\</SolutionBinFolderAbsolutePath>
|
||||
<WebAppFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebApp\</WebAppFolderRelativeToProjects>
|
||||
<WebAppFolderAbsolutePath>$(BuildFolderAbsolutePath)WebApp\</WebAppFolderAbsolutePath>
|
||||
<WebPiFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebPi\</WebPiFolderRelativeToProjects>
|
||||
<WebPiFolderAbsolutePath>$(BuildFolderAbsolutePath)WebPi\</WebPiFolderAbsolutePath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<BuildConfiguration>Release</BuildConfiguration>
|
||||
<BuildFolder>_BuildOutput\</BuildFolder>
|
||||
<BuildZipFileName>UmbracoCms$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileName>
|
||||
<BuildZipFileNameBin>UmbracoCms.AllBinaries$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameBin>
|
||||
<BuildZipFileNameWebPi>UmbracoCms.WebPI$(DECIMAL_BUILD_NUMBER).zip</BuildZipFileNameWebPi>
|
||||
<IncludeSymbols>False</IncludeSymbols>
|
||||
<BuildFolderRelativeToProjects>..\..\build\$(BuildFolder)</BuildFolderRelativeToProjects>
|
||||
<BuildFolderAbsolutePath>$(MSBuildProjectDirectory)\$(BuildFolder)</BuildFolderAbsolutePath>
|
||||
<SolutionBinFolder>$(BuildFolder)bin\</SolutionBinFolder>
|
||||
<WebAppFolder>$(BuildFolder)WebApp\</WebAppFolder>
|
||||
<WebPiFolder>$(BuildFolder)WebPi\</WebPiFolder>
|
||||
<SolutionBinFolderRelativeToProjects>$(BuildFolderRelativeToProjects)bin\</SolutionBinFolderRelativeToProjects>
|
||||
<SolutionBinFolderAbsolutePath>$(BuildFolderAbsolutePath)bin\</SolutionBinFolderAbsolutePath>
|
||||
<WebAppFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebApp\</WebAppFolderRelativeToProjects>
|
||||
<WebAppFolderAbsolutePath>$(BuildFolderAbsolutePath)WebApp\</WebAppFolderAbsolutePath>
|
||||
<WebPiFolderRelativeToProjects>$(BuildFolderRelativeToProjects)WebPi\</WebPiFolderRelativeToProjects>
|
||||
<WebPiFolderAbsolutePath>$(BuildFolderAbsolutePath)WebPi\</WebPiFolderAbsolutePath>
|
||||
<ExaminePDFPath>$(BuildFolderAbsolutePath)UmbracoExamine.PDF\</ExaminePDFPath>
|
||||
<ExamineAzurePath>$(BuildFolderAbsolutePath)UmbracoExamine.Azure\</ExamineAzurePath>
|
||||
<ExaminePDFAzurePath>$(BuildFolderAbsolutePath)UmbracoExamine.PDF.Azure\</ExaminePDFAzurePath>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<SystemFolders Include="$(WebAppFolder)App_Plugins" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Code" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Data" />
|
||||
<SystemFolders Include="$(WebAppFolder)media" />
|
||||
<SystemFolders Include="$(WebAppFolder)masterpages" />
|
||||
<SystemFolders Include="$(WebAppFolder)scripts" />
|
||||
<SystemFolders Include="$(WebAppFolder)css" />
|
||||
<SystemFolders Include="$(WebAppFolder)macroScripts" />
|
||||
<SystemFolders Include="$(WebAppFolder)xslt" />
|
||||
<SystemFolders Include="$(WebAppFolder)usercontrols" />
|
||||
<SystemFolders Include="$(WebAppFolder)Views" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<SystemFolders Include="$(WebAppFolder)App_Plugins" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Code" />
|
||||
<SystemFolders Include="$(WebAppFolder)App_Data" />
|
||||
<SystemFolders Include="$(WebAppFolder)Media" />
|
||||
<SystemFolders Include="$(WebAppFolder)Masterpages" />
|
||||
<SystemFolders Include="$(WebAppFolder)Scripts" />
|
||||
<SystemFolders Include="$(WebAppFolder)Css" />
|
||||
<SystemFolders Include="$(WebAppFolder)MacroScripts" />
|
||||
<SystemFolders Include="$(WebAppFolder)Xslt" />
|
||||
<SystemFolders Include="$(WebAppFolder)UserControls" />
|
||||
<SystemFolders Include="$(WebAppFolder)Views" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
<!--
|
||||
****************************************************
|
||||
TARGETS
|
||||
*****************************************************
|
||||
-->
|
||||
|
||||
<Target Name="Build" DependsOnTargets="GenerateWebPiHash">
|
||||
<Message Text="Build finished" />
|
||||
<Message Text="Build finished" />
|
||||
</Target>
|
||||
|
||||
<Target Name="GenerateWebPiHash" DependsOnTargets="ZipWebPiApp">
|
||||
@@ -123,154 +120,117 @@
|
||||
</ItemGroup>
|
||||
<Message Text="Calculating hash for $(BuildZipFileNameWebPi)" />
|
||||
<GenerateHash InputFiles="@(WebPiFile)" OutputFile="webpihash.txt" />
|
||||
</Target>
|
||||
</Target>
|
||||
|
||||
<Target Name="CleanUp" DependsOnTargets="ZipWebPiApp">
|
||||
<Message Text="Deleting $(BuildFolder)" Importance="high" />
|
||||
<RemoveDir Directories="$(BuildFolder)" />
|
||||
<Message Text="Finished deleting $(BuildFolder)" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CleanUp" DependsOnTargets="ZipWebPiApp">
|
||||
<Message Text="Deleting $(BuildFolder)" Importance="high" />
|
||||
<RemoveDir Directories="$(BuildFolder)" />
|
||||
<Message Text="Finished deleting $(BuildFolder)" Importance="high" />
|
||||
</Target>
|
||||
<Target Name="ZipWebPiApp" DependsOnTargets="ZipWebApp" >
|
||||
<!-- Clean folders -->
|
||||
<RemoveDir Directories="$(WebPiFolder)" />
|
||||
<MakeDir Directories="$(WebPiFolder)" />
|
||||
<MakeDir Directories="$(WebPiFolder)umbraco" />
|
||||
|
||||
<Target Name="ZipWebPiApp" DependsOnTargets="ZipWebApp" >
|
||||
<!-- Clean folders -->
|
||||
<RemoveDir Directories="$(WebPiFolder)" />
|
||||
<MakeDir Directories="$(WebPiFolder)" />
|
||||
<MakeDir Directories="$(WebPiFolder)umbraco" />
|
||||
<!-- Copy fresh built umbraco files -->
|
||||
<Exec Command="xcopy %22$(WebAppFolderAbsolutePath)*%22 %22$(WebPiFolderAbsolutePath)umbraco%22 /S /E /Y /I" />
|
||||
|
||||
<!-- Copy Web Pi template files -->
|
||||
<ItemGroup>
|
||||
<WebPiFiles Include="..\src\WebPi\**\*.*" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Copy fresh built umbraco files -->
|
||||
<Exec Command="xcopy %22$(WebAppFolderAbsolutePath)*%22 %22$(WebPiFolderAbsolutePath)umbraco%22 /S /E /Y /I" />
|
||||
<Copy SourceFiles="@(WebPiFiles)"
|
||||
DestinationFiles="@(WebPiFiles->'$(WebPiFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||
|
||||
<!-- Copy Web Pi template files -->
|
||||
<ItemGroup>
|
||||
<WebPiFiles Include="..\src\WebPi\**\*.*" />
|
||||
</ItemGroup>
|
||||
<!-- Zip the files -->
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22" />
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipWebApp" DependsOnTargets="CreateSystemFolders" >
|
||||
<Message Text="Starting to zip to $(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
|
||||
<Copy SourceFiles="@(WebPiFiles)"
|
||||
DestinationFiles="@(WebPiFiles->'$(WebPiFolder)%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameBin)%22 %22$(SolutionBinFolderAbsolutePath)*%22" />
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileName)%22 %22$(WebAppFolderAbsolutePath)*%22" />
|
||||
|
||||
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<!-- Zip the files -->
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameWebPi)%22 %22$(WebPiFolderAbsolutePath)*%22" />
|
||||
</Target>
|
||||
|
||||
<Target Name="ZipWebApp" DependsOnTargets="CreateSystemFolders" >
|
||||
<Message Text="Starting to zip to $(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileNameBin)%22 %22$(SolutionBinFolderAbsolutePath)*%22" />
|
||||
<Exec Command="..\tools\7zip\7za.exe a -r %22$(BuildZipFileName)%22 %22$(WebAppFolderAbsolutePath)*%22" />
|
||||
|
||||
<Message Text="Finished zipping to build\$(BuildFolder)\$(buildDate)-$(BuildZipFileName)" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CreateSystemFolders" DependsOnTargets="CopyLibraries" Inputs="@(SystemFolders)" Outputs="%(Identity).Dummy">
|
||||
<MakeDir Directories="@(SystemFolders)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyLibraries" DependsOnTargets="OffsetTimestamps" >
|
||||
<!-- Copy SQL CE -->
|
||||
<ItemGroup>
|
||||
<SQLCE4Files
|
||||
Include="..\src\packages\SqlServerCE.4.0.0.0\**\*.*"
|
||||
Exclude="..\src\packages\SqlServerCE.4.0.0.0\lib\**\*;..\src\packages\SqlServerCE.4.0.0.0\**\*.nu*"
|
||||
<Target Name="CreateSystemFolders" DependsOnTargets="CopyLibraries" Inputs="@(SystemFolders)" Outputs="%(Identity).Dummy">
|
||||
<MakeDir Directories="@(SystemFolders)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CopyLibraries" DependsOnTargets="OffsetTimestamps" >
|
||||
<!-- Copy SQL CE -->
|
||||
<ItemGroup>
|
||||
<SQLCE4Files
|
||||
Include="..\src\packages\SqlServerCE.4.0.0.0\**\*.*"
|
||||
Exclude="..\src\packages\SqlServerCE.4.0.0.0\lib\**\*;..\src\packages\SqlServerCE.4.0.0.0\**\*.nu*"
|
||||
/>
|
||||
</ItemGroup>
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(SQLCE4Files)"
|
||||
DestinationFiles="@(SQLCE4Files->'$(SolutionBinFolder)%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Copy SourceFiles="@(SQLCE4Files)"
|
||||
DestinationFiles="@(SQLCE4Files->'$(SolutionBinFolder)%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
<Copy SourceFiles="@(SQLCE4Files)"
|
||||
DestinationFiles="@(SQLCE4Files->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Copy SourceFiles="@(SQLCE4Files)"
|
||||
DestinationFiles="@(SQLCE4Files->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
|
||||
</Target>
|
||||
|
||||
</Target>
|
||||
<!-- Offset the modified timestamps on all umbraco dlls, as WebResources break if date is in the future, which, due to timezone offsets can happen. -->
|
||||
<Target Name="OffsetTimestamps" DependsOnTargets="CopyTransformedWebConfig">
|
||||
<CreateItem Include="$(BuildFolder)**\umbraco.*.dll">
|
||||
<Output TaskParameter="Include" ItemName="FilesToOffsetTimestamp" />
|
||||
</CreateItem>
|
||||
<Message Text="Starting to offset timestamps" Importance="high" />
|
||||
<Umbraco.MSBuild.Tasks.TimestampOffset Files="@(FilesToOffsetTimestamp)" Offset="-11" />
|
||||
<Message Text="Finished offsetting timestamps" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the transformed web.config file to the root -->
|
||||
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyXmlDocumentation">
|
||||
<ItemGroup>
|
||||
<WebConfigFile Include="..\src\Umbraco.Web.UI\web.$(BuildConfiguration).Config.transformed" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(WebConfigFile)"
|
||||
DestinationFiles="$(WebAppFolder)Web.config"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the xml documentation to the bin folder -->
|
||||
<Target Name="CopyXmlDocumentation" DependsOnTargets="CompileProjects">
|
||||
<ItemGroup>
|
||||
<XmlDocumentationFiles Include="$(SolutionBinFolder)*.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(XmlDocumentationFiles)"
|
||||
DestinationFiles="@(XmlDocumentationFiles->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Message Text="CopyXmlDocumentation" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileProjects" DependsOnTargets="SetVersionNumber">
|
||||
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
|
||||
<!-- For UseWPP_CopyWebApplication=True see http://stackoverflow.com/questions/1983575/copywebapplication-with-web-config-transformations -->
|
||||
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath)" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
</MSBuild>
|
||||
|
||||
<!-- Offset the modified timestamps on all umbraco dlls, as WebResources break if date is in the future, which, due to timezone offsets can happen. -->
|
||||
<Target Name="OffsetTimestamps" DependsOnTargets="CopyTransformedWebConfig">
|
||||
<CreateItem Include="$(BuildFolder)**\umbraco.*.dll">
|
||||
<Output TaskParameter="Include" ItemName="FilesToOffsetTimestamp" />
|
||||
</CreateItem>
|
||||
<Message Text="Starting to offset timestamps" Importance="high" />
|
||||
<Umbraco.MSBuild.Tasks.TimestampOffset Files="@(FilesToOffsetTimestamp)" Offset="-11" />
|
||||
<Message Text="Finished offsetting timestamps" Importance="high" />
|
||||
</Target>
|
||||
<!-- DONE -->
|
||||
<Message Text="Finished compiling projects" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the transformed web.config file to the root -->
|
||||
<Target Name="CopyTransformedWebConfig" DependsOnTargets="CopyXmlDocumentation">
|
||||
<ItemGroup>
|
||||
<WebConfigFile Include="..\src\Umbraco.Web.UI\web.$(BuildConfiguration).Config.transformed" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(WebConfigFile)"
|
||||
DestinationFiles="$(WebAppFolder)Web.config"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the xml documentation to the bin folder -->
|
||||
<Target Name="CopyXmlDocumentation" DependsOnTargets="CompileProjects">
|
||||
<ItemGroup>
|
||||
<XmlDocumentationFiles Include="$(SolutionBinFolder)*.xml" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(XmlDocumentationFiles)"
|
||||
DestinationFiles="@(XmlDocumentationFiles->'$(WebAppFolder)bin\%(RecursiveDir)%(Filename)%(Extension)')"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Message Text="CopyXmlDocumentation" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileProjects" DependsOnTargets="CompileExternalExamineProjects">
|
||||
|
||||
<Message Text="Compiling web project to build\$(BuildFolder)" Importance="high" />
|
||||
<!-- For UseWPP_CopyWebApplication=True see http://stackoverflow.com/questions/1983575/copywebapplication-with-web-config-transformations -->
|
||||
<!-- Build the Umbraco.Web.UI project -->
|
||||
<MSBuild Projects="..\src\Umbraco.Web.UI\Umbraco.Web.UI.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);UseWPP_CopyWebApplication=True;PipelineDependsOnBuild=False;OutDir=$(SolutionBinFolderAbsolutePath);WebProjectOutputDir=$(WebAppFolderAbsolutePath)" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
</MSBuild>
|
||||
|
||||
<!-- DONE -->
|
||||
<Message Text="Finished compiling projects" Importance="high" />
|
||||
</Target>
|
||||
|
||||
<Target Name="CompileExternalExamineProjects" DependsOnTargets="SetVersionNumber">
|
||||
<Message Text="Building externally shipped examine projects" Importance="high" />
|
||||
|
||||
<!-- First remove old files from the examine builds -->
|
||||
<ItemGroup>
|
||||
<FilesToDeleteBeforeBuild Include="$(ExaminePDFPath)*;$(ExamineAzurePath)*"/>
|
||||
</ItemGroup>
|
||||
<Delete Files="@(FilesToDeleteBeforeBuild)" />
|
||||
<!--
|
||||
Build the UmbracoExamine.PDF.Azure library ... this builds the 3 projects that we want to bundle separately so no need to build each one separately .
|
||||
We'll just build this one and then manually copy the DLLs to where we want them.
|
||||
-->
|
||||
<MSBuild Projects="..\src\UmbracoExamine.PDF.Azure\UmbracoExamine.PDF.Azure.csproj" Properties="WarningLevel=0;Configuration=$(BuildConfiguration);PipelineDependsOnBuild=False;OutDir=$(ExaminePDFAzurePath);" Targets="Clean;Build;" BuildInParallel="False" ToolsVersion="4.0" UnloadProjectsOnCompletion="False">
|
||||
</MSBuild>
|
||||
<ItemGroup>
|
||||
<ExaminePDFFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.pdf;$(ExaminePDFAzurePath)**\UmbracoExamine.PDF.xml;$(ExaminePDFAzurePath)**\itextsharp.dll" />
|
||||
<ExamineAzureFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.pdb;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.xml" />
|
||||
<ExaminePDFAzureFiles Include="$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.dll;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.pdb;$(ExaminePDFAzurePath)**\UmbracoExamine.Azure.PDF.xml" />
|
||||
</ItemGroup>
|
||||
<!-- Now copy the built files to their correct deployment folders-->
|
||||
<Copy SourceFiles="@(ExaminePDFFiles)"
|
||||
DestinationFolder="$(ExaminePDFPath)"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<Copy SourceFiles="@(ExamineAzureFiles)"
|
||||
DestinationFolder="$(ExamineAzurePath)"
|
||||
OverwriteReadOnlyFiles="true"
|
||||
SkipUnchangedFiles="false" />
|
||||
<!-- Then just delete the files we don't want to ship in the UmbracoExamine.Azure.PDF folder -->
|
||||
<ItemGroup>
|
||||
<FilesToDeleteAfterBuild Include="$(ExaminePDFAzurePath)*" Exclude="$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.dll;$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.pdb;$(ExaminePDFAzurePath)UmbracoExamine.PDF.Azure.xml"/>
|
||||
</ItemGroup>
|
||||
<Delete Files="@(FilesToDeleteAfterBuild)" />
|
||||
</Target>
|
||||
|
||||
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<Target Name="SetVersionNumber" Condition="'$(BUILD_RELEASE)'!=''">
|
||||
<!-- Match & replace 3 and 4 digit version numbers and -beta (if it's there) -->
|
||||
<FileUpdate
|
||||
<FileUpdate
|
||||
Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Regex="(\d+)\.(\d+)\.(\d+)(.(\d+))?"
|
||||
ReplacementText="$(BUILD_RELEASE)"/>
|
||||
@@ -278,5 +238,5 @@
|
||||
<FileUpdate Files="..\src\Umbraco.Core\Configuration\UmbracoVersion.cs"
|
||||
Regex="CurrentComment { get { return "([a-zA-Z]+)?""
|
||||
ReplacementText="CurrentComment { get { return "$(BUILD_COMMENT)""/>
|
||||
</Target>
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -16,7 +16,7 @@
|
||||
<tags>umbraco</tags>
|
||||
<dependencies>
|
||||
<dependency id="Microsoft.AspNet.Mvc" version="[4.0.20710.0]" />
|
||||
<dependency id="Microsoft.AspNet.WebApi" version="4.0.20710.0" />
|
||||
<dependency id="ServiceStack.Text" version="3.9.21" />
|
||||
<dependency id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="1.0.0" />
|
||||
</dependencies>
|
||||
</metadata>
|
||||
|
||||
@@ -21,7 +21,4 @@ if ($project) {
|
||||
$projectDestinationPath = Split-Path $project.FullName -Parent
|
||||
$umbracoFilesPath = Join-Path $rootPath "UmbracoFiles\*"
|
||||
Copy-Item $umbracoFilesPath $projectDestinationPath -recurse -force
|
||||
|
||||
# Open readme.txt file
|
||||
$DTE.ItemOperations.OpenFile($toolsPath + '\Readme.txt')
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
@ECHO OFF
|
||||
|
||||
:choice
|
||||
set /P c=WARNING! Are you sure you want to continue, this will remove all package files, view files, sqlce database, etc... Press 'Y' to auto-remove all files/folders, 'N' to cancel or 'C' to prompt for each folder removal?
|
||||
if /I "%c%" EQU "C" goto :prompt
|
||||
if /I "%c%" EQU "Y" goto :auto
|
||||
if /I "%c%" EQU "N" goto :exit
|
||||
goto :choice
|
||||
|
||||
|
||||
:prompt
|
||||
|
||||
echo Current folder: %CD%
|
||||
|
||||
echo Regenerating SQL CE database
|
||||
SET buildfolder=%CD%
|
||||
CD ..\tools\RegenerateUmbracoSQLCEDatabase\
|
||||
RegenerateUmbracoSQLCEDatabase.exe %CD%\..\..\src\Umbraco.Web.UI
|
||||
CD %buildfolder%
|
||||
|
||||
echo Removing bin files
|
||||
del ..\src\Umbraco.Web.UI\bin\*.*
|
||||
|
||||
echo Building solution
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe ..\src\umbraco.sln /t:Clean,Build
|
||||
|
||||
echo Resetting installedPackages.config
|
||||
echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config
|
||||
|
||||
echo Removing plugin cache files
|
||||
del ..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*
|
||||
|
||||
echo Removing cache files and examine index
|
||||
del ..\src\Umbraco.Web.UI\App_Data\TEMP\*.*
|
||||
|
||||
echo Removing log files
|
||||
del ..\src\Umbraco.Web.UI\App_Data\Logs\*.*
|
||||
|
||||
echo Removing packages
|
||||
del ..\src\Umbraco.Web.UI\App_Data\packages\*.*
|
||||
|
||||
echo Removing previews
|
||||
del ..\src\Umbraco.Web.UI\App_Data\preview\*.*
|
||||
|
||||
echo Removing app code files (typically added by starterkits)
|
||||
del ..\src\Umbraco.Web.UI\App_Code\*.*
|
||||
|
||||
echo Removing xslt files
|
||||
del ..\src\Umbraco.Web.UI\xslt\*.*
|
||||
|
||||
echo Removing user control files
|
||||
del ..\src\Umbraco.Web.UI\UserControls\*.*
|
||||
|
||||
echo Removing masterpage files
|
||||
del ..\src\Umbraco.Web.UI\masterpages\*.*
|
||||
|
||||
echo Removing view files
|
||||
del ..\src\Umbraco.Web.UI\Views\*.*
|
||||
|
||||
echo Removing razor files
|
||||
del ..\src\Umbraco.Web.UI\macroScripts\*.*
|
||||
|
||||
echo Removing media files
|
||||
del ..\src\Umbraco.Web.UI\media\*.*
|
||||
|
||||
echo Removing script files
|
||||
del ..\src\Umbraco.Web.UI\scripts\*.*
|
||||
|
||||
echo Removing css files
|
||||
del ..\src\Umbraco.Web.UI\css\*.*
|
||||
|
||||
echo "Umbraco install reverted to clean install"
|
||||
pause
|
||||
exit
|
||||
|
||||
|
||||
|
||||
:auto
|
||||
|
||||
echo Current folder: %CD%
|
||||
|
||||
echo Regenerating SQL CE database
|
||||
SET buildfolder=%CD%
|
||||
CD ..\tools\RegenerateUmbracoSQLCEDatabase\
|
||||
RegenerateUmbracoSQLCEDatabase.exe %CD%\..\..\src\Umbraco.Web.UI
|
||||
CD %buildfolder%
|
||||
|
||||
echo Removing bin files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\bin\*.*) DO DEL %%A
|
||||
|
||||
echo Building solution
|
||||
%windir%\Microsoft.NET\Framework\v4.0.30319\msbuild.exe ..\src\umbraco.sln /t:Clean,Build
|
||||
|
||||
echo Resetting installedPackages.config
|
||||
echo ^<?xml version="1.0" encoding="utf-8"?^>^<packages^>^</packages^> >..\src\Umbraco.Web.UI\App_Data\packages\installed\installedPackages.config
|
||||
|
||||
echo Removing plugin cache files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\PluginCache\*.*) DO DEL %%A
|
||||
|
||||
echo Removing cache files and examine index
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\TEMP\*.*) DO DEL %%A
|
||||
|
||||
echo Removing log files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\Logs\*.*) DO DEL %%A
|
||||
|
||||
echo Removing packages
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\packages\*.*) DO DEL %%A
|
||||
|
||||
echo Removing previews
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Data\preview\*.*) DO DEL %%A
|
||||
|
||||
echo Removing app code files (typically added by starterkits)
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\App_Code\*.*) DO DEL %%A
|
||||
|
||||
echo Removing xslt files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\xslt\*.*) DO DEL %%A
|
||||
|
||||
echo Removing masterpage files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\masterpages\*.*) DO DEL %%A
|
||||
|
||||
echo Removing user control files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\usercontrols\*.*) DO DEL %%A
|
||||
|
||||
echo Removing view files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\Views\*.*) DO DEL %%A
|
||||
|
||||
echo Removing razor files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\macroScripts\*.*) DO DEL %%A
|
||||
|
||||
echo Removing media files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\media\*.*) DO DEL %%A
|
||||
|
||||
echo Removing script files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\scripts\*.*) DO DEL %%A
|
||||
|
||||
echo Removing css files
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\css\*.*) DO DEL %%A
|
||||
|
||||
echo Removing Courier files
|
||||
del ..\src\Umbraco.Web.UI\config\courier.config
|
||||
del ..\src\Umbraco.Web.UI\umbraco\images\tray\courier.jpg
|
||||
rmdir "..\src\Umbraco.Web.UI\umbraco\plugins\courier\" /S /Q
|
||||
|
||||
echo Removing Contour files
|
||||
del ..\src\Umbraco.Web.UI\umbraco\images\tray\contour.png
|
||||
FOR %%A IN (..\src\Umbraco.Web.UI\umbraco\images\umbraco\icon_*.*) DO DEL %%A
|
||||
rmdir "..\src\Umbraco.Web.UI\umbraco\plugins\umbracoContour\" /S /Q
|
||||
del ..\src\Umbraco.Web.UI\umbraco\xslt\templates\UmbracoContour*.* /S /Q
|
||||
rmdir "..\src\Umbraco.Web.UI\usercontrols\umbracoContour\" /S /Q
|
||||
|
||||
echo Start with a clean web.config
|
||||
copy ..\src\Umbraco.Web.UI\web.Template.config ..\src\Umbraco.Web.UI\web.config /Y
|
||||
|
||||
echo "Umbraco install reverted to clean install"
|
||||
pause
|
||||
exit
|
||||
|
||||
|
||||
|
||||
:exit
|
||||
exit
|
||||
Binary file not shown.
@@ -1,24 +0,0 @@
|
||||
Hi! Thanks for grabbing the Umbraco sourcecode.
|
||||
|
||||
===========================================
|
||||
NOTE - DEFAULT BRANCH EMPTY - December 2010
|
||||
===========================================
|
||||
|
||||
|
||||
- With the help of CodePlex we have migrated much of our previous changesets (as of Dec 13th 2010) from TFS to Mercurial.
|
||||
|
||||
- However, not everything could be migrated to our new branching workflow. So for each nominal group of 4.x changes, we've created named branches. For upcoming 5.x changesets, we'll adhere to our new workflow which we'll describe on the Wiki for contributors.
|
||||
|
||||
- FOR THE MOMENT, the 'default' branch is empty - pending the addition of the 5.0 changesets
|
||||
|
||||
- To switch to the codebase on which you want to work, 'hg update' to the named branch (e.g. "4.6.0") or tag (e.g. "Release-4.5.2") and browse or work from that point.
|
||||
|
||||
|
||||
Thanks to Matt Hawley at CodePlex for his help in our migration!
|
||||
|
||||
Cheers,
|
||||
The Umbraco Team
|
||||
|
||||
http://umbraco.org
|
||||
http://our.umbraco.org
|
||||
http://umbraco.codeplex.com
|
||||
@@ -1,82 +0,0 @@
|
||||
{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f36\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}
|
||||
{\f39\froman\fcharset238\fprq2 Times New Roman CE;}{\f40\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f42\froman\fcharset161\fprq2 Times New Roman Greek;}{\f43\froman\fcharset162\fprq2 Times New Roman Tur;}
|
||||
{\f44\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f45\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f46\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f47\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}
|
||||
{\f399\fswiss\fcharset238\fprq2 Tahoma CE;}{\f400\fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f402\fswiss\fcharset161\fprq2 Tahoma Greek;}{\f403\fswiss\fcharset162\fprq2 Tahoma Tur;}{\f404\fswiss\fcharset177\fprq2 Tahoma (Hebrew);}
|
||||
{\f405\fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f406\fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f407\fswiss\fcharset163\fprq2 Tahoma (Vietnamese);}{\f408\fswiss\fcharset222\fprq2 Tahoma (Thai);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;
|
||||
\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;
|
||||
\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \snext0 Normal;}{\*\cs10 \additive
|
||||
\ssemihidden Default Paragraph Font;}{\*\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv
|
||||
\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\s15\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
|
||||
\f36\fs16\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \sbasedon0 \snext15 \ssemihidden \styrsid668380 Balloon Text;}}{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\listtable{\list\listtemplateid130696116{\listlevel\levelnfc0\levelnfcn0\leveljc0
|
||||
\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\fi-360\li720\jclisttab\tx720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0
|
||||
{\leveltext\'02\'01.;}{\levelnumbers\'01;}\fi-360\li1440\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\fi-360\li2160
|
||||
\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\fi-360\li2880\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc0\levelnfcn0\leveljc0
|
||||
\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\fi-360\li3600\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0
|
||||
{\leveltext\'02\'05.;}{\levelnumbers\'01;}\fi-360\li4320\jclisttab\tx4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\fi-360\li5040
|
||||
\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\fi-360\li5760\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc0\levelnfcn0\leveljc0
|
||||
\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\fi-360\li6480\jclisttab\tx6480\lin6480 }{\listname ;}\listid723138990}}{\*\listoverridetable{\listoverride\listid723138990\listoverridecount0\ls1}}
|
||||
{\*\pgptbl {\pgp\ipgp2\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp4\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}{\pgp\ipgp0\itap0\li0\ri0\sb0\sa0}}{\*\rsidtbl \rsid288726\rsid668380\rsid1077358\rsid1250157\rsid1778664
|
||||
\rsid2232581\rsid3018318\rsid3766585\rsid4417501\rsid4531485\rsid4807452\rsid5341002\rsid7018004\rsid7880391\rsid10749719\rsid12150908\rsid12939982\rsid13596669\rsid15149892\rsid15551579\rsid16128754\rsid16674677}{\*\generator Microsoft Word 11.0.6359;}
|
||||
{\info{\title Shared Source License for Software included in Workspaces}{\author suev}{\operator Martin Maly}{\creatim\yr2005\mo3\dy22\hr10\min45}{\revtim\yr2005\mo3\dy22\hr15\min54}{\printim\yr2002\mo9\dy20\hr15\min39}{\version3}{\edmins1}{\nofpages1}
|
||||
{\nofwords672}{\nofchars3837}{\*\company Microsoft}{\nofcharsws4501}{\vern24703}}\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984
|
||||
\dghshow1\dgvshow1\jexpand\viewkind5\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
|
||||
\asianbrkrule\nojkernpunct\rsidroot15149892 \fet0\sectd \linex0\endnhere\sectlinegrid360\sectdefaultcl\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3
|
||||
\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}
|
||||
{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain
|
||||
\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 {\b\fs28\insrsid1250157\charrsid1250157 Shared Source License for }{\b\fs28\insrsid16674677 IronPython}{
|
||||
\b\fs28\insrsid1250157
|
||||
\par }{\b\fs28\insrsid5341002
|
||||
\par }{\b\insrsid5341002\charrsid5341002 This license governs use of the accompanying software}{\b\insrsid5341002 (\'93Software\'94)}{\b\insrsid5341002\charrsid5341002 , and your use of the }{\b\insrsid5341002 S}{\b\insrsid5341002\charrsid5341002
|
||||
oftware constitutes acceptance of this license.
|
||||
\par }{\insrsid1250157\charrsid5341002
|
||||
\par }{\b\insrsid1250157\charrsid1250157 You }{\b\insrsid5341002 may}{\b\insrsid1250157\charrsid1250157 use }{\b\insrsid5341002 the}{\b\insrsid1250157\charrsid1250157 Software for any }{\b\insrsid1250157 commercial or }{\b\insrsid1250157\charrsid1250157
|
||||
noncommercial purpose, including distributing derivative}{\b\insrsid4417501 work}{\b\insrsid1250157\charrsid1250157 s}{\b\insrsid1250157 .
|
||||
\par }{\insrsid1250157
|
||||
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1250157 {\insrsid1250157\charrsid1250157 In return, we simply require that you agree:
|
||||
\par {\listtext\pard\plain\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 1.\tab}}\pard \ql \fi-360\li720\ri0\widctlpar\jclisttab\tx720\aspalpha\aspnum\faauto\ls1\adjustright\rin0\lin720\itap0\pararsid1250157 {\insrsid1250157\charrsid1250157
|
||||
Not to remove any copyright}{\insrsid5341002 or other}{\insrsid1250157\charrsid1250157 notices from the Software.
|
||||
\par {\listtext\pard\plain\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 2.\tab}That if you distribute the Software in source code form you do so only under this }{\insrsid5341002 l}{\insrsid1250157\charrsid1250157
|
||||
icense (i.e. you must include a complete copy of this }{\insrsid5341002 l}{\insrsid1250157\charrsid1250157 icense with your distribution), and if you distribute the Software solely in object form you only do so under a license that complies with this }{
|
||||
\insrsid5341002 l}{\insrsid1250157\charrsid1250157 icense.
|
||||
\par {\listtext\pard\plain\b\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 3.\tab}}{\b\insrsid1250157\charrsid1250157
|
||||
That the Software comes "as is", with no warranties. None whatsoever. This means no express, implied or statutory warranty, including without limitation, warranties of merchantability or fitness for a particular purpose or any warranty of }{
|
||||
\b\insrsid5341002 title or }{\b\insrsid1250157\charrsid1250157 non}{\b\insrsid5341002 -}{\b\insrsid1250157\charrsid1250157 infringement. Also, you must pass this disclaimer on whenever you distribute the Software}{\b\insrsid5341002 or derivative works}{
|
||||
\b\insrsid1250157\charrsid1250157 .}{\insrsid1250157\charrsid1250157
|
||||
\par {\listtext\pard\plain\b\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 4.\tab}}{\b\insrsid1250157\charrsid1250157 That neither Microsoft nor }{\b\insrsid1250157 any contributor to the Software}{\b\insrsid1250157\charrsid1250157
|
||||
will be liable for any of those types of damages known as}{\b\insrsid5341002 }{\b\insrsid1250157\charrsid1250157 indirect, special, consequential, or incidental related to the Software or this }{\b\insrsid5341002 l}{\b\insrsid1250157\charrsid1250157
|
||||
icense, to the maximum extent the law permits, no matter what legal theory it\rquote s based on. Also, you must pass this limitation of liability on whenever you distribute the Software}{\b\insrsid5341002 or derivative works}{
|
||||
\b\insrsid1250157\charrsid1250157 .}{\insrsid1250157\charrsid1250157
|
||||
\par {\listtext\pard\plain\insrsid1250157\charrsid1250157 \hich\af0\dbch\af0\loch\f0 5.\tab}That if you sue anyone over patents that you think may apply to the Software for a person's use of the Software, your license to the Software ends automatically.
|
||||
|
||||
\par {\listtext\pard\plain\insrsid1250157 \hich\af0\dbch\af0\loch\f0 6.\tab}}{\insrsid1250157 That the patent rights, if any, }{\insrsid288726 granted in this license}{\insrsid1250157\charrsid1250157 only apply to the Software, not to any derivative}{
|
||||
\insrsid4417501 work}{\insrsid1250157\charrsid1250157 s you make.}{\insrsid3018318
|
||||
\par {\listtext\pard\plain\insrsid3018318\charrsid3018318 \hich\af0\dbch\af0\loch\f0 7.\tab}}{\insrsid3018318\charrsid3018318 That if you are an agency of the U.S. Government, (i) Software provided pursuant to a solicitation issued on or after Dece
|
||||
mber 1, 1995, is provided with the commercial license rights set forth in this license, and (ii) Software provided pursuant to a solicitation issued prior to December 1, 1995, is provided with \'93Restricted Rights\'94
|
||||
as set forth in FAR, 48 C.F.R. 52.227-14 (June 1987) or DFAR, 48 C.F.R. 252.227-7013 (Oct 1988), as applicable.}{\insrsid1250157
|
||||
\par {\listtext\pard\plain\insrsid1250157 \hich\af0\dbch\af0\loch\f0 8.\tab}That your rights under this License end automatically if you breach it in any way.
|
||||
\par {\listtext\pard\plain\insrsid5341002 \hich\af0\dbch\af0\loch\f0 9.\tab}}{\insrsid5341002 That all rights not expressly granted to you in this license are reserved.
|
||||
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid1778664 {\insrsid1778664
|
||||
\par }{\insrsid12150908 Read below}{\insrsid1778664 for answers to frequently asked questions about this license.
|
||||
\par }{\insrsid12150908
|
||||
\par }\pard \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid12150908 {\b\insrsid12150908\charrsid12150908 Q: Is this license OSI compliant?
|
||||
\par }{\insrsid12150908
|
||||
A: This license has not been submitted to OSI, but it allows developers to take full advantage of a dynamic language on the CLR and to have the freedom to distribute their works for the benefit of the community at large. The license is half of a
|
||||
page long and very straight forward. We believe it stands up to what developers demand of an "open" license.
|
||||
\par
|
||||
\par }{\b\insrsid12150908\charrsid12150908 Q: What copyright rights does the license grant me?
|
||||
\par }{\insrsid12150908 A: The license grants you a copyright license to make unlimited copies of the Software in sour
|
||||
ce or object code form, as well as to create Derivative Works (as that term is defined under US copyright law). This means that in addition to making unlimited copies of the Software, you have a copyright license to modify the Software and to use all or p
|
||||
art of the Software to create a Derivative Work.
|
||||
\par
|
||||
\par }{\b\insrsid12150908\charrsid12150908 Q: What patent rights does the license grant me?
|
||||
\par }{\insrsid12150908 A: This license grants you a patent license to use and distribute the Software under any Microsoft patent claims that read on the Software itself. In other wo
|
||||
rds, if you create a modified version of the Software, you still retain the patent license to use and distribute the original portions of the Software under the specific Microsoft patent claims that read on the Software, but you do not have a patent licen
|
||||
s
|
||||
e as to the new functionality you may have added by modifying the Software. This result is typical of many common open source licenses, including the Common Public License (CPL) and the Mozilla Public License (MPL). In addition, this license grants no rig
|
||||
h
|
||||
ts to any Microsoft patents that read on other components or files not included in the Software. This means that no patent license is granted to use or distribute any other software or technology that may be needed to use the Software or was created from
|
||||
t
|
||||
he Software (for example, any compiled output of the Software, the combination of the Software with other hardware or other software, or any additional enabling technologies that may be necessary to make or use the Software or any final product that inclu
|
||||
des the Software).}{\insrsid12150908
|
||||
\par }{\insrsid12150908\charrsid1250157
|
||||
\par }}
|
||||
+30
-6
@@ -1,9 +1,33 @@
|
||||
!! Umbraco - the simple, flexible and friendly ASP.NET CMS
|
||||
Umbraco - the simple, flexible and friendly ASP.NET CMS
|
||||
=======================================================
|
||||
For the first time on the Microsoft platform a free user and developer friendly cms that makes it quick and easy to create websites - or a breeze to build complex web applications. umbraco got award-winning integration capabilities and supports your ASP.NET User and Custom Controls out of the box. It's a developers dream and your users will love it too. Used by more than 57.000 active websites including Heinz.com, Peugeot.com, NAIAS.com and Microsofts documentinteropinitiative.org website you can be sure that the technology is proven, stable and scales.
|
||||
[url:More info at http://umbraco.org|http://umbraco.org]
|
||||
|
||||
!! Forums
|
||||
We have a forum running on [url:http://our.umbraco.org]. The discussions area on CodePlex will be for discussions on developing the core, and not on Umbraco-implementations or extensions in general. For those topics, please use [url:http://our.umbraco.org].
|
||||
More info at http://umbraco.com
|
||||
|
||||
!! Submitting Issues
|
||||
Another way you can contribute to Umbraco is by providing issue reports, for information on how to submit an issue report refer to our [url:online guide|http://our.umbraco.org/wiki/how-tos/submitting-bug-reports].
|
||||
Exploring the repository
|
||||
========================
|
||||
Most contributors will work on their own fork and should pick the branch in which they need their fix. For more information see:
|
||||
http://our.umbraco.org/contribute/guidelines-for-core-contribution
|
||||
|
||||
Exploring the source
|
||||
====================
|
||||
The Umbraco source code is never required for you to start building sites. If you are not using the source code for debugging purposes or to contribute to the source then please download the binaries listed at http://umbraco.codeplex.com
|
||||
|
||||
With that said, the Umbraco solution can be opened in Visual Studio 2010 with SP1 installed or Visual Studio 2012.
|
||||
|
||||
Contributing
|
||||
============
|
||||
Umbraco is Open Source which means you can contribute to make it great!
|
||||
Read all about it at http://our.umbraco.org/contribute
|
||||
|
||||
Forums
|
||||
======
|
||||
We have a forum running on http://our.umbraco.org for friendly community support.
|
||||
|
||||
Documentation
|
||||
=============
|
||||
Our documentation section provides help on installing and using Umbraco including API reference documentation: http://our.umbraco.org/documentation
|
||||
|
||||
Submitting Issues
|
||||
=================
|
||||
Another way you can contribute to Umbraco is by providing issue reports, for information on how to submit an issue report refer to our online guide at http://our.umbraco.org/contribute/report-an-issue-or-request-a-feature
|
||||
@@ -1,12 +1,9 @@
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
|
||||
@@ -18,53 +15,33 @@ namespace Umbraco.Core
|
||||
/// <remarks>
|
||||
/// one per AppDomain, represents the global Umbraco application
|
||||
/// </remarks>
|
||||
public class ApplicationContext : IDisposable
|
||||
public class ApplicationContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext)
|
||||
: this(dbContext, serviceContext, true)
|
||||
:this()
|
||||
{
|
||||
|
||||
if (dbContext == null) throw new ArgumentNullException("dbContext");
|
||||
if (serviceContext == null) throw new ArgumentNullException("serviceContext");
|
||||
|
||||
_databaseContext = dbContext;
|
||||
_services = serviceContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <param name="enableCache"></param>
|
||||
internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, bool enableCache)
|
||||
: this(enableCache)
|
||||
{
|
||||
if (dbContext == null) throw new ArgumentNullException("dbContext");
|
||||
if (serviceContext == null) throw new ArgumentNullException("serviceContext");
|
||||
|
||||
_databaseContext = dbContext;
|
||||
_services = serviceContext;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Empty constructor normally reserved for unit tests when a DatabaseContext or a ServiceContext is not
|
||||
/// necessarily required or needs to be set after construction.
|
||||
/// </summary>
|
||||
internal ApplicationContext() : this(true)
|
||||
{
|
||||
internal ApplicationContext()
|
||||
{
|
||||
//create a new application cache from the HttpRuntime.Cache
|
||||
ApplicationCache = HttpRuntime.Cache == null
|
||||
? new CacheHelper(new Cache())
|
||||
: new CacheHelper(HttpRuntime.Cache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor used to specify if we will enable application cache or not
|
||||
/// </summary>
|
||||
/// <param name="enableCache"></param>
|
||||
internal ApplicationContext(bool enableCache)
|
||||
{
|
||||
//create a new application cache from the HttpRuntime.Cache
|
||||
ApplicationCache = HttpRuntime.Cache == null
|
||||
? new CacheHelper(new System.Web.Caching.Cache(), enableCache)
|
||||
: new CacheHelper(HttpRuntime.Cache, enableCache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Singleton accessor
|
||||
/// </summary>
|
||||
@@ -123,6 +100,18 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The original/first url that the web application executes
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// we need to set the initial url in our ApplicationContext, this is so our keep alive service works and this must
|
||||
/// exist on a global context because the keep alive service doesn't run in a web context.
|
||||
/// we are NOT going to put a lock on this because locking will slow down the application and we don't really care
|
||||
/// if two threads write to this at the exact same time during first page hit.
|
||||
/// see: http://issues.umbraco.org/issue/U4-2059
|
||||
/// </remarks>
|
||||
internal string OriginalRequestUrl { get; set; }
|
||||
|
||||
private bool Configured
|
||||
{
|
||||
get
|
||||
@@ -163,7 +152,6 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void AssertIsReady()
|
||||
{
|
||||
if (!this.IsReady)
|
||||
@@ -209,54 +197,5 @@ namespace Umbraco.Core
|
||||
}
|
||||
internal set { _services = value; }
|
||||
}
|
||||
|
||||
|
||||
private volatile bool _disposed;
|
||||
private readonly ReaderWriterLockSlim _disposalLocker = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// This will dispose and reset all resources used to run the application
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// IMPORTANT: Never dispose this object if you require the Umbraco application to run, disposing this object
|
||||
/// is generally used for unit testing and when your application is shutting down after you have booted Umbraco.
|
||||
/// </remarks>
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
// Only operate if we haven't already disposed
|
||||
if (_disposed) return;
|
||||
|
||||
using (new WriteLock(_disposalLocker))
|
||||
{
|
||||
// Check again now we're inside the lock
|
||||
if (_disposed) return;
|
||||
|
||||
//clear the cache
|
||||
if (ApplicationCache != null)
|
||||
{
|
||||
ApplicationCache.ClearAllCache();
|
||||
}
|
||||
//reset all resolvers
|
||||
ResolverCollection.ResetAll();
|
||||
//reset resolution itself (though this should be taken care of by resetting any of the resolvers above)
|
||||
Resolution.Reset();
|
||||
|
||||
//reset the instance objects
|
||||
this.ApplicationCache = null;
|
||||
if (_databaseContext != null) //need to check the internal field here
|
||||
{
|
||||
if (DatabaseContext.Database != null)
|
||||
{
|
||||
DatabaseContext.Database.Dispose();
|
||||
}
|
||||
}
|
||||
this.DatabaseContext = null;
|
||||
this.Services = null;
|
||||
this._isReady = false; //set the internal field
|
||||
|
||||
// Indicate that the instance has been disposed.
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A plugin type that allows developers to execute code during the Umbraco bootup process
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Allows you to override the methods that you would like to execute code for: ApplicationInitialized, ApplicationStarting, ApplicationStarted.
|
||||
///
|
||||
/// By default none of these methods will execute if the Umbraco application is not configured or if the Umbraco database is not configured, however
|
||||
/// if you need these methods to execute even if either of these are not configured you can override the properties:
|
||||
/// ExecuteWhenApplicationNotConfigured and ExecuteWhenDatabaseNotConfigured
|
||||
/// </remarks>
|
||||
public abstract class ApplicationEventHandler : IApplicationEventHandler
|
||||
{
|
||||
public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
if (ShouldExecute(applicationContext))
|
||||
{
|
||||
ApplicationInitialized(umbracoApplication, applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
if (ShouldExecute(applicationContext))
|
||||
{
|
||||
ApplicationStarting(umbracoApplication, applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
if (ShouldExecute(applicationContext))
|
||||
{
|
||||
ApplicationStarted(umbracoApplication, applicationContext);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridable method to execute when the ApplicationContext is created and other static objects that require initialization have been setup
|
||||
/// </summary>
|
||||
/// <param name="umbracoApplication"></param>
|
||||
/// <param name="applicationContext"></param>
|
||||
protected virtual void ApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OVerridable method to execute when All resolvers have been initialized but resolution is not frozen so they can be modified in this method
|
||||
/// </summary>
|
||||
/// <param name="umbracoApplication"></param>
|
||||
/// <param name="applicationContext"></param>
|
||||
protected virtual void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overridable method to execute when Bootup is completed, this allows you to perform any other bootup logic required for the application.
|
||||
/// Resolution is frozen so now they can be used to resolve instances.
|
||||
/// </summary>
|
||||
/// <param name="umbracoApplication"></param>
|
||||
/// <param name="applicationContext"></param>
|
||||
protected virtual void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine if the methods should execute based on the configuration status of the application.
|
||||
/// </summary>
|
||||
/// <param name="applicationContext"></param>
|
||||
/// <returns></returns>
|
||||
private bool ShouldExecute(ApplicationContext applicationContext)
|
||||
{
|
||||
if (applicationContext.IsConfigured && applicationContext.DatabaseContext.IsDatabaseConfigured)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!applicationContext.IsConfigured && ExecuteWhenApplicationNotConfigured)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!applicationContext.DatabaseContext.IsDatabaseConfigured && ExecuteWhenDatabaseNotConfigured)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A flag to determine if the overridable methods for this class will execute even if the
|
||||
/// Umbraco application is not configured
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// An Umbraco Application is not configured when it requires a new install or upgrade. When the latest version in the
|
||||
/// assembly does not match the version in the config.
|
||||
/// </remarks>
|
||||
protected virtual bool ExecuteWhenApplicationNotConfigured
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A flag to determine if the overridable methods for this class will execute even if the
|
||||
/// Umbraco database is not configured
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The Umbraco database is not configured when we cannot connect to the database or when the database tables are not installed.
|
||||
/// </remarks>
|
||||
protected virtual bool ExecuteWhenDatabaseNotConfigured
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Constants storing cache keys used in caching
|
||||
/// </summary>
|
||||
public static class CacheKeys
|
||||
{
|
||||
public const string ApplicationTreeCacheKey = "ApplicationTreeCache";
|
||||
public const string ApplicationsCacheKey = "ApplicationCache";
|
||||
|
||||
public const string UserTypeCacheKey = "UserTypeCache";
|
||||
|
||||
public const string ContentItemCacheKey = "contentItem";
|
||||
|
||||
public const string MediaCacheKey = "UL_GetMedia";
|
||||
|
||||
public const string MacroXsltCacheKey = "macroXslt_";
|
||||
public const string MacroCacheKey = "UmbracoMacroCache";
|
||||
public const string MacroHtmlCacheKey = "macroHtml_";
|
||||
public const string MacroControlCacheKey = "macroControl_";
|
||||
public const string MacroHtmlDateAddedCacheKey = "macroHtml_DateAdded_";
|
||||
public const string MacroControlDateAddedCacheKey = "macroControl_DateAdded_";
|
||||
|
||||
public const string MemberLibraryCacheKey = "UL_GetMember";
|
||||
public const string MemberBusinessLogicCacheKey = "MemberCacheItem_";
|
||||
|
||||
public const string TemplateFrontEndCacheKey = "template";
|
||||
public const string TemplateBusinessLogicCacheKey = "UmbracoTemplateCache";
|
||||
|
||||
public const string UserContextCacheKey = "UmbracoUserContext";
|
||||
public const string UserContextTimeoutCacheKey = "UmbracoUserContextTimeout";
|
||||
public const string UserCacheKey = "UmbracoUser";
|
||||
|
||||
public const string ContentTypeCacheKey = "UmbracoContentType";
|
||||
|
||||
public const string ContentTypePropertiesCacheKey = "ContentType_PropertyTypes_Content:";
|
||||
|
||||
public const string PropertyTypeCacheKey = "UmbracoPropertyTypeCache";
|
||||
|
||||
public const string LanguageCacheKey = "UmbracoLanguageCache";
|
||||
|
||||
public const string DomainCacheKey = "UmbracoDomainList";
|
||||
|
||||
public const string StylesheetCacheKey = "UmbracoStylesheet";
|
||||
public const string StylesheetPropertyCacheKey = "UmbracoStylesheetProperty";
|
||||
|
||||
public const string DataTypeCacheKey = "UmbracoDataTypeDefinition";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// An abstract class for implementing a cache helper
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// THIS MUST REMAIN INTERNAL UNTIL WE STREAMLINE HOW ALL CACHE IS HANDLED, WE NEED TO SUPPORT HTTP RUNTIME CACHE, IN MEMORY CACHE, ETC...
|
||||
/// </remarks>
|
||||
internal abstract class CacheProviderBase
|
||||
{
|
||||
public abstract void ClearAllCache();
|
||||
public abstract void ClearCacheItem(string key);
|
||||
public abstract void ClearCacheObjectTypes(string typeName);
|
||||
public abstract void ClearCacheObjectTypes<T>();
|
||||
public abstract void ClearCacheByKeySearch(string keyStartsWith);
|
||||
public abstract void ClearCacheByKeyExpression(string regexString);
|
||||
public abstract IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith);
|
||||
public abstract T GetCacheItem<T>(string cacheKey);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
public abstract void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem);
|
||||
}
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Sync;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for cache refreshers to inherit from that ensures the correct events are raised
|
||||
/// when cache refreshing occurs.
|
||||
/// </summary>
|
||||
/// <typeparam name="TInstanceType">The real cache refresher type, this is used for raising strongly typed events</typeparam>
|
||||
public abstract class CacheRefresherBase<TInstanceType> : ICacheRefresher
|
||||
where TInstanceType : ICacheRefresher
|
||||
{
|
||||
/// <summary>
|
||||
/// An event that is raised when cache is updated on an individual server
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This event will fire on each server configured for an Umbraco project whenever a cache refresher
|
||||
/// is updated.
|
||||
/// </remarks>
|
||||
public static event TypedEventHandler<TInstanceType, CacheRefresherEventArgs> CacheUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Raises the event
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="args"></param>
|
||||
protected static void OnCacheUpdated(TInstanceType sender, CacheRefresherEventArgs args)
|
||||
{
|
||||
if (CacheUpdated != null)
|
||||
{
|
||||
CacheUpdated(sender, args);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the real instance of the object ('this') for use in strongly typed events
|
||||
/// </summary>
|
||||
protected abstract TInstanceType Instance { get; }
|
||||
|
||||
public abstract Guid UniqueIdentifier { get; }
|
||||
|
||||
public abstract string Name { get; }
|
||||
|
||||
public virtual void RefreshAll()
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(null, MessageType.RefreshAll));
|
||||
}
|
||||
|
||||
public virtual void Refresh(int id)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RefreshById));
|
||||
}
|
||||
|
||||
public virtual void Remove(int id)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RemoveById));
|
||||
}
|
||||
|
||||
public virtual void Refresh(Guid id)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(id, MessageType.RefreshById));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Sync;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Event args for cache refresher updates
|
||||
/// </summary>
|
||||
public class CacheRefresherEventArgs : EventArgs
|
||||
{
|
||||
public CacheRefresherEventArgs(object msgObject, MessageType type)
|
||||
{
|
||||
MessageType = type;
|
||||
MessageObject = msgObject;
|
||||
}
|
||||
public object MessageObject { get; private set; }
|
||||
public MessageType MessageType { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,356 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A CacheProvider that wraps the logic of the HttpRuntime.Cache
|
||||
/// </summary>
|
||||
internal class HttpRuntimeCacheProvider : CacheProviderBase
|
||||
{
|
||||
private readonly System.Web.Caching.Cache _cache;
|
||||
private static readonly object Locker = new object();
|
||||
|
||||
public HttpRuntimeCacheProvider(System.Web.Caching.Cache cache)
|
||||
{
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears everything in umbraco's runtime cache, which means that not only
|
||||
/// umbraco content is removed, but also other cache items from pages running in
|
||||
/// the same application / website. Use with care :-)
|
||||
/// </summary>
|
||||
public override void ClearAllCache()
|
||||
{
|
||||
var cacheEnumerator = _cache.GetEnumerator();
|
||||
while (cacheEnumerator.MoveNext())
|
||||
{
|
||||
_cache.Remove(cacheEnumerator.Key.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the item in umbraco's runtime cache with the given key
|
||||
/// </summary>
|
||||
/// <param name="key">Key</param>
|
||||
public override void ClearCacheItem(string key)
|
||||
{
|
||||
// NH 10 jan 2012
|
||||
// Patch by the always wonderful Stéphane Gay to avoid cache null refs
|
||||
lock (Locker)
|
||||
{
|
||||
if (_cache[key] == null) return;
|
||||
_cache.Remove(key); ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the System.Web.Cache with the System.Type name as the
|
||||
/// input parameter. (using [object].GetType())
|
||||
/// </summary>
|
||||
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
|
||||
public override void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
foreach (DictionaryEntry c in _cache)
|
||||
{
|
||||
if (_cache[c.Key.ToString()] != null
|
||||
&& _cache[c.Key.ToString()].GetType().ToString().InvariantEquals(typeName))
|
||||
{
|
||||
_cache.Remove(c.Key.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error<CacheHelper>("Cache clearing error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the System.Web.Cache with the System.Type specified
|
||||
/// </summary>
|
||||
public override void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
try
|
||||
{
|
||||
lock (Locker)
|
||||
{
|
||||
foreach (DictionaryEntry c in _cache)
|
||||
{
|
||||
if (_cache[c.Key.ToString()] != null
|
||||
&& _cache[c.Key.ToString()].GetType() == typeof(T))
|
||||
{
|
||||
_cache.Remove(c.Key.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LogHelper.Error<CacheHelper>("Cache clearing error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that starts with the key passed.
|
||||
/// </summary>
|
||||
/// <param name="keyStartsWith">The start of the key</param>
|
||||
public override void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
foreach (DictionaryEntry c in _cache)
|
||||
{
|
||||
if (c.Key is string && ((string)c.Key).InvariantStartsWith(keyStartsWith))
|
||||
{
|
||||
ClearCacheItem((string)c.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that have a key that matches the regular expression
|
||||
/// </summary>
|
||||
/// <param name="regexString"></param>
|
||||
public override void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
foreach (DictionaryEntry c in _cache)
|
||||
{
|
||||
if (c.Key is string && Regex.IsMatch(((string)c.Key), regexString))
|
||||
{
|
||||
ClearCacheItem((string)c.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
return (from DictionaryEntry c in _cache
|
||||
where c.Key is string && ((string)c.Key).InvariantStartsWith(keyStartsWith)
|
||||
select c.Value.TryConvertTo<T>()
|
||||
into attempt
|
||||
where attempt.Success
|
||||
select attempt.Result).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a cache item by key, does not update the cache if it isn't there.
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey)
|
||||
{
|
||||
var result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
return default(TT);
|
||||
}
|
||||
return result.TryConvertTo<TT>().Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with all of the default parameters
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, CacheItemPriority.Normal, null, null, null, getCacheItem, Locker);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey,
|
||||
TimeSpan? timeout, Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, null, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemRemovedCallback refreshAction, TimeSpan? timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, CacheItemPriority.Normal, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, priority, refreshAction, null, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public override TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan? timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
return GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem, Locker);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <param name="syncLock"></param>
|
||||
/// <returns></returns>
|
||||
private TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency, TimeSpan? timeout, Func<TT> getCacheItem, object syncLock)
|
||||
{
|
||||
var result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
result = getCacheItem();
|
||||
if (result != null)
|
||||
{
|
||||
//we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it.
|
||||
_cache.Insert(cacheKey, result, cacheDependency,
|
||||
timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value),
|
||||
TimeSpan.Zero, priority, refreshAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.TryConvertTo<TT>().Result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public override void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
InsertCacheItem(cacheKey, priority, null, null, null, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public override void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
InsertCacheItem(cacheKey, priority, null, null, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public override void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
InsertCacheItem(cacheKey, priority, null, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public override void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
object result = getCacheItem();
|
||||
if (result != null)
|
||||
{
|
||||
//we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it.
|
||||
_cache.Insert(cacheKey, result, cacheDependency,
|
||||
timeout == null ? System.Web.Caching.Cache.NoAbsoluteExpiration : DateTime.Now.Add(timeout.Value),
|
||||
TimeSpan.Zero, priority, refreshAction);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// Strongly type cache refresher that is able to refresh cache of real instances of objects as well as IDs
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <remarks>
|
||||
/// This is much better for performance when we're not running in a load balanced environment so we can refresh the cache
|
||||
/// against a already resolved object instead of looking the object back up by id.
|
||||
/// </remarks>
|
||||
interface ICacheRefresher<T> : ICacheRefresher
|
||||
{
|
||||
void Refresh(T instance);
|
||||
void Remove(T instance);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A cache refresher that supports refreshing or removing cache based on a custom Json payload
|
||||
/// </summary>
|
||||
interface IJsonCacheRefresher : ICacheRefresher
|
||||
{
|
||||
/// <summary>
|
||||
/// Refreshes, clears, etc... any cache based on the information provided in the json
|
||||
/// </summary>
|
||||
/// <param name="jsonPayload"></param>
|
||||
void Refresh(string jsonPayload);
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using Umbraco.Core.Sync;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for json cache refreshers that ensures the correct events are raised when
|
||||
/// cache refreshing occurs.
|
||||
/// </summary>
|
||||
/// <typeparam name="TInstanceType">The real cache refresher type, this is used for raising strongly typed events</typeparam>
|
||||
public abstract class JsonCacheRefresherBase<TInstanceType> : CacheRefresherBase<TInstanceType>, IJsonCacheRefresher
|
||||
where TInstanceType : ICacheRefresher
|
||||
{
|
||||
|
||||
public virtual void Refresh(string jsonPayload)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(jsonPayload, MessageType.RefreshByJson));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Caching;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
internal class NullCacheProvider : CacheProviderBase
|
||||
{
|
||||
public override void ClearAllCache()
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearCacheItem(string key)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
}
|
||||
|
||||
public override IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
return Enumerable.Empty<T>();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, Func<T> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public override T GetCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
return getCacheItem();
|
||||
}
|
||||
|
||||
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, Func<T> getCacheItem)
|
||||
{
|
||||
}
|
||||
|
||||
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
}
|
||||
|
||||
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
}
|
||||
|
||||
public override void InsertCacheItem<T>(string cacheKey, CacheItemPriority priority, CacheItemRemovedCallback refreshAction, CacheDependency cacheDependency, TimeSpan? timeout, Func<T> getCacheItem)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using Umbraco.Core.Sync;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for cache refreshers to inherit from that ensures the correct events are raised
|
||||
/// when cache refreshing occurs.
|
||||
/// </summary>
|
||||
/// <typeparam name="TInstanceType">The real cache refresher type, this is used for raising strongly typed events</typeparam>
|
||||
/// <typeparam name="TEntityType">The entity type that this refresher can update cache for</typeparam>
|
||||
public abstract class TypedCacheRefresherBase<TInstanceType, TEntityType> : CacheRefresherBase<TInstanceType>, ICacheRefresher<TEntityType>
|
||||
where TInstanceType : ICacheRefresher
|
||||
{
|
||||
public virtual void Refresh(TEntityType instance)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(instance, MessageType.RefreshByInstance));
|
||||
}
|
||||
|
||||
public virtual void Remove(TEntityType instance)
|
||||
{
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(instance, MessageType.RemoveByInstance));
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
-311
@@ -3,10 +3,8 @@ using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -18,33 +16,29 @@ namespace Umbraco.Core
|
||||
/// <remarks>
|
||||
/// This class may be opened publicly at some point but needs a review of what is absoletely necessary.
|
||||
/// </remarks>
|
||||
public class CacheHelper //: CacheProviderBase
|
||||
public class CacheHelper
|
||||
{
|
||||
private readonly bool _enableCache;
|
||||
private readonly HttpRuntimeCacheProvider _httpCache;
|
||||
private readonly NullCacheProvider _nullCache = new NullCacheProvider();
|
||||
private readonly Cache _cache;
|
||||
|
||||
public CacheHelper(System.Web.Caching.Cache cache)
|
||||
: this(cache, true)
|
||||
{
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
internal CacheHelper(System.Web.Caching.Cache cache, bool enableCache)
|
||||
{
|
||||
_httpCache = new HttpRuntimeCacheProvider(cache);
|
||||
_enableCache = enableCache;
|
||||
}
|
||||
|
||||
private static readonly object Locker = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Clears everything in umbraco's runtime cache, which means that not only
|
||||
/// umbraco content is removed, but also other cache items from pages running in
|
||||
/// the same application / website. Use with care :-)
|
||||
/// </summary>
|
||||
public void ClearAllCache()
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.ClearAllCache();
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearAllCache();
|
||||
}
|
||||
var cacheEnumerator = _cache.GetEnumerator();
|
||||
while (cacheEnumerator.MoveNext())
|
||||
{
|
||||
_cache.Remove(cacheEnumerator.Key.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -53,13 +47,12 @@ namespace Umbraco.Core
|
||||
/// <param name="key">Key</param>
|
||||
public void ClearCacheItem(string key)
|
||||
{
|
||||
if (!_enableCache)
|
||||
// NH 10 jan 2012
|
||||
// Patch by the always wonderful Stéphane Gay to avoid cache null refs
|
||||
lock (Locker)
|
||||
{
|
||||
_nullCache.ClearCacheItem(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheItem(key);
|
||||
if (_cache[key] == null) return;
|
||||
_cache.Remove(key);;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,191 +64,54 @@ namespace Umbraco.Core
|
||||
/// <param name="typeName">The name of the System.Type which should be cleared from cache ex "System.Xml.XmlDocument"</param>
|
||||
public void ClearCacheObjectTypes(string typeName)
|
||||
{
|
||||
if (!_enableCache)
|
||||
try
|
||||
{
|
||||
_nullCache.ClearCacheObjectTypes(typeName);
|
||||
lock (Locker)
|
||||
{
|
||||
foreach (var c in from DictionaryEntry c in _cache where _cache[c.Key.ToString()] != null && _cache[c.Key.ToString()].GetType().ToString() == typeName select c)
|
||||
{
|
||||
_cache.Remove(c.Key.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (Exception e)
|
||||
{
|
||||
_httpCache.ClearCacheObjectTypes(typeName);
|
||||
LogHelper.Error<CacheHelper>("Cache clearing error", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all objects in the System.Web.Cache with the System.Type specified
|
||||
/// </summary>
|
||||
public void ClearCacheObjectTypes<T>()
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheObjectTypes<T>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that starts with the key passed.
|
||||
/// </summary>
|
||||
/// <param name="keyStartsWith">The start of the key</param>
|
||||
public void ClearCacheByKeySearch(string keyStartsWith)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheByKeySearch(keyStartsWith);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears all cache items that have a key that matches the regular expression
|
||||
/// </summary>
|
||||
/// <param name="regexString"></param>
|
||||
public void ClearCacheByKeyExpression(string regexString)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.ClearCacheByKeyExpression(regexString);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetCacheItemsByKeySearch<T>(string keyStartsWith)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItemsByKeySearch<T>(keyStartsWith);
|
||||
}
|
||||
foreach (var c in from DictionaryEntry c in _cache where c.Key is string && ((string)c.Key).StartsWith(keyStartsWith) select c)
|
||||
{
|
||||
ClearCacheItem((string)c.Key);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a cache item by key, does not update the cache if it isn't there.
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with all of the default parameters
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey, Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
TimeSpan timeout, Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, timeout, getCacheItem);
|
||||
}
|
||||
return GetCacheItem(cacheKey, null, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemRemovedCallback refreshAction, TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
return GetCacheItem(cacheKey, CacheItemPriority.Normal, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction, TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, timeout, getCacheItem);
|
||||
}
|
||||
return GetCacheItem(cacheKey, priority, refreshAction, null, timeout, getCacheItem);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache with the specified absolute expiration date (from NOW)
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
@@ -263,136 +119,46 @@ namespace Umbraco.Core
|
||||
TimeSpan timeout,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
return GetCacheItem(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem, Locker);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and adds if necessary) an item from the cache
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <returns></returns>
|
||||
public TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheDependency cacheDependency,
|
||||
Func<TT> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
return _nullCache.GetCacheItem<TT>(cacheKey, priority, null, cacheDependency, null, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _httpCache.GetCacheItem<TT>(cacheKey, priority, null, cacheDependency, null, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.InsertCacheItem<T>(cacheKey, priority, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
TimeSpan timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.InsertCacheItem<T>(cacheKey, priority, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.InsertCacheItem<T>(cacheKey, priority, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts an item into the cache, if it already exists in the cache it will be replaced
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout">This will set an absolute expiration from now until the timeout</param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
public void InsertCacheItem<T>(string cacheKey,
|
||||
CacheItemPriority priority,
|
||||
CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency,
|
||||
TimeSpan? timeout,
|
||||
Func<T> getCacheItem)
|
||||
{
|
||||
if (!_enableCache)
|
||||
{
|
||||
_nullCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
_httpCache.InsertCacheItem<T>(cacheKey, priority, refreshAction, cacheDependency, timeout, getCacheItem);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// This is used only for legacy purposes as I did not want to change all of the locking to one lock found on this object,
|
||||
/// however, the reason this is used for legacy purposes is because I see zero reason to use different sync locks, just the one
|
||||
/// lock (Locker) on this class should be sufficient.
|
||||
/// </summary>
|
||||
/// <typeparam name="TT"></typeparam>
|
||||
/// <param name="cacheKey"></param>
|
||||
/// <param name="priority"></param>
|
||||
/// <param name="refreshAction"></param>
|
||||
/// <param name="cacheDependency"></param>
|
||||
/// <param name="timeout"></param>
|
||||
/// <param name="getCacheItem"></param>
|
||||
/// <param name="syncLock"></param>
|
||||
/// <returns></returns>
|
||||
internal TT GetCacheItem<TT>(string cacheKey,
|
||||
CacheItemPriority priority, CacheItemRemovedCallback refreshAction,
|
||||
CacheDependency cacheDependency, TimeSpan timeout, Func<TT> getCacheItem, object syncLock)
|
||||
{
|
||||
var result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
result = _cache.Get(cacheKey);
|
||||
if (result == null)
|
||||
{
|
||||
result = getCacheItem();
|
||||
if (result != null)
|
||||
{
|
||||
//we use Insert instead of add if for some crazy reason there is now a cache with the cache key in there, it will just overwrite it.
|
||||
_cache.Insert(cacheKey, result, cacheDependency, DateTime.Now.Add(timeout), TimeSpan.Zero, priority, refreshAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (TT)result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureIsInitialized();
|
||||
EnsureIdsAreTracked();
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.CodeAnnotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute to add a Friendly Name string with an UmbracoObjectType enum value
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = false)]
|
||||
internal class FriendlyNameAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// friendly name value
|
||||
/// </summary>
|
||||
private readonly string _friendlyName;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the FriendlyNameAttribute class
|
||||
/// Sets the friendly name value
|
||||
/// </summary>
|
||||
/// <param name="friendlyName">attribute value</param>
|
||||
public FriendlyNameAttribute(string friendlyName)
|
||||
{
|
||||
this._friendlyName = friendlyName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the friendly name
|
||||
/// </summary>
|
||||
/// <returns>string of friendly name</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return this._friendlyName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.CodeAnnotations
|
||||
{
|
||||
/// <summary>
|
||||
/// Attribute to associate a GUID string and Type with an UmbracoObjectType Enum value
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
|
||||
internal class UmbracoObjectTypeAttribute : Attribute
|
||||
{
|
||||
public UmbracoObjectTypeAttribute(string objectId)
|
||||
{
|
||||
ObjectId = new Guid(objectId);
|
||||
}
|
||||
|
||||
public UmbracoObjectTypeAttribute(string objectId, Type modelType)
|
||||
{
|
||||
ObjectId = new Guid(objectId);
|
||||
ModelType = modelType;
|
||||
}
|
||||
|
||||
public Guid ObjectId { get; private set; }
|
||||
|
||||
public Type ModelType { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A thread-safe representation of a <see cref="HashSet{T}"/>.
|
||||
/// Enumerating this collection is thread-safe and will only operate on a clone that is generated before returning the enumerator.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[Serializable]
|
||||
public class ConcurrentHashSet<T> : ICollection<T>
|
||||
{
|
||||
private readonly HashSet<T> _innerSet = new HashSet<T>();
|
||||
private readonly ReaderWriterLockSlim _instanceLocker = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through the collection.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
|
||||
/// </returns>
|
||||
/// <filterpriority>1</filterpriority>
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return GetThreadSafeClone().GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through a collection.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
|
||||
/// </returns>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if <paramref name="item"/> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false. This method also returns false if <paramref name="item"/> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
/// </returns>
|
||||
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
|
||||
public bool Remove(T item)
|
||||
{
|
||||
using (new WriteLock(_instanceLocker))
|
||||
{
|
||||
return _innerSet.Remove(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The number of elements contained in the <see cref="T:System.Collections.ICollection"/>.
|
||||
/// </returns>
|
||||
/// <filterpriority>2</filterpriority>
|
||||
public int Count
|
||||
{
|
||||
get { return GetThreadSafeClone().Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if the <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only; otherwise, false.
|
||||
/// </returns>
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
/// </summary>
|
||||
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param><exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only.</exception>
|
||||
public void Add(T item)
|
||||
{
|
||||
using (new WriteLock(_instanceLocker))
|
||||
{
|
||||
_innerSet.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to add an item to the collection
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public bool TryAdd(T item)
|
||||
{
|
||||
var clone = GetThreadSafeClone();
|
||||
if (clone.Contains(item)) return false;
|
||||
using (new WriteLock(_instanceLocker))
|
||||
{
|
||||
//double check
|
||||
if (_innerSet.Contains(item)) return false;
|
||||
_innerSet.Add(item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1"/>.
|
||||
/// </summary>
|
||||
/// <exception cref="T:System.NotSupportedException">The <see cref="T:System.Collections.Generic.ICollection`1"/> is read-only. </exception>
|
||||
public void Clear()
|
||||
{
|
||||
using (new WriteLock(_instanceLocker))
|
||||
{
|
||||
_innerSet.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1"/> contains a specific value.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// true if <paramref name="item"/> is found in the <see cref="T:System.Collections.Generic.ICollection`1"/>; otherwise, false.
|
||||
/// </returns>
|
||||
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1"/>.</param>
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return GetThreadSafeClone().Contains(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the elements of the <see cref="T:System.Collections.Concurrent.IProducerConsumerCollection`1"/> to an <see cref="T:System.Array"/>, starting at a specified index.
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from the <see cref="T:System.Collections.Concurrent.IProducerConsumerCollection`1"/>. The array must have zero-based indexing.</param><param name="index">The zero-based index in <paramref name="array"/> at which copying begins.</param><exception cref="T:System.ArgumentNullException"><paramref name="array"/> is a null reference (Nothing in Visual Basic).</exception><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is less than zero.</exception><exception cref="T:System.ArgumentException"><paramref name="index"/> is equal to or greater than the length of the <paramref name="array"/> -or- The number of elements in the source <see cref="T:System.Collections.Concurrent.ConcurrentQueue`1"/> is greater than the available space from <paramref name="index"/> to the end of the destination <paramref name="array"/>.</exception>
|
||||
public void CopyTo(T[] array, int index)
|
||||
{
|
||||
var clone = GetThreadSafeClone();
|
||||
clone.CopyTo(array, index);
|
||||
}
|
||||
|
||||
private HashSet<T> GetThreadSafeClone()
|
||||
{
|
||||
HashSet<T> clone = null;
|
||||
using (new WriteLock(_instanceLocker))
|
||||
{
|
||||
clone = new HashSet<T>(_innerSet, _innerSet.Comparer);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copies the elements of the <see cref="T:System.Collections.ICollection"/> to an <see cref="T:System.Array"/>, starting at a particular <see cref="T:System.Array"/> index.
|
||||
/// </summary>
|
||||
/// <param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the elements copied from <see cref="T:System.Collections.ICollection"/>. The <see cref="T:System.Array"/> must have zero-based indexing. </param><param name="index">The zero-based index in <paramref name="array"/> at which copying begins. </param><exception cref="T:System.ArgumentNullException"><paramref name="array"/> is null. </exception><exception cref="T:System.ArgumentOutOfRangeException"><paramref name="index"/> is less than zero. </exception><exception cref="T:System.ArgumentException"><paramref name="array"/> is multidimensional.-or- The number of elements in the source <see cref="T:System.Collections.ICollection"/> is greater than the available space from <paramref name="index"/> to the end of the destination <paramref name="array"/>. </exception><exception cref="T:System.ArgumentException">The type of the source <see cref="T:System.Collections.ICollection"/> cannot be cast automatically to the type of the destination <paramref name="array"/>. </exception><filterpriority>2</filterpriority>
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
var clone = GetThreadSafeClone();
|
||||
Array.Copy(clone.ToArray(), 0, array, index, clone.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// A case-insensitive configuration converter for enumerations.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the enumeration.</typeparam>
|
||||
internal class CaseInsensitiveEnumConfigConverter<T> : ConfigurationConverterBase
|
||||
where T : struct
|
||||
{
|
||||
public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException("data");
|
||||
|
||||
//return Enum.Parse(typeof(T), (string)data, true);
|
||||
|
||||
T value;
|
||||
if (Enum.TryParse((string)data, true, out value))
|
||||
return value;
|
||||
|
||||
throw new Exception(string.Format("\"{0}\" is not valid {1} value. Valid values are: {2}.",
|
||||
data, typeof(T).Name,
|
||||
string.Join(", ", Enum.GetValues(typeof(T)).Cast<T>())));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates the configuration key for a section or a group.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
internal sealed class ConfigurationKeyAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConfigurationKeyAttribute"/> class with a configuration key.
|
||||
/// </summary>
|
||||
/// <param name="configurationKey">The configurationkey.</param>
|
||||
public ConfigurationKeyAttribute(string configurationKey)
|
||||
{
|
||||
ConfigurationKey = configurationKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the configuration key.
|
||||
/// </summary>
|
||||
public string ConfigurationKey { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -42,24 +42,15 @@ namespace Umbraco.Core.Configuration
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config)
|
||||
/// used for unit tests
|
||||
/// </summary>
|
||||
private static void ResetInternal()
|
||||
internal static void ResetCache()
|
||||
{
|
||||
_reservedUrlsCache = null;
|
||||
_reservedPaths = null;
|
||||
_reservedUrls = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets settings that were set programmatically, to their initial values.
|
||||
/// </summary>
|
||||
/// <remarks>To be used in unit tests.</remarks>
|
||||
internal static void Reset()
|
||||
{
|
||||
ResetInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reserved urls from web.config.
|
||||
/// </summary>
|
||||
@@ -584,16 +575,6 @@ namespace Umbraco.Core.Configuration
|
||||
return context.Request.Path.ToLower().IndexOf(SystemDirectories.Umbraco.ToLower() + "/liveediting.aspx") > -1;
|
||||
}
|
||||
|
||||
public static bool RequestIsInUmbracoApplication(HttpContextBase context)
|
||||
{
|
||||
return context.Request.Path.ToLower().IndexOf(IOHelper.ResolveUrl(SystemDirectories.Umbraco).ToLower()) > -1;
|
||||
}
|
||||
|
||||
public static bool RequestIsLiveEditRedirector(HttpContextBase context)
|
||||
{
|
||||
return context.Request.Path.ToLower().IndexOf(SystemDirectories.Umbraco.ToLower() + "/liveediting.aspx") > -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether umbraco should force a secure (https) connection to the backoffice.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
using System.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
{
|
||||
// note - still must work on how to support read-only and ResetSection for collections
|
||||
// note - still must work on how to spread config over files (aka DeepConfig in v5)
|
||||
|
||||
/// <summary>
|
||||
/// Represents an Umbraco section within the configuration file.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The requirement for these sections is to be read-only.</para>
|
||||
/// <para>However for unit tests purposes it is internally possible to override some values, and
|
||||
/// then calling <c>>ResetSection</c> should cancel these changes and bring the section back to
|
||||
/// what it was originally.</para>
|
||||
/// <para>The <c>UmbracoSettings.For{T}</c> method will return a section, either one that
|
||||
/// is in the configuration file, or a section that was created with default values.</para>
|
||||
/// </remarks>
|
||||
internal abstract class UmbracoConfigurationSection : ConfigurationSection
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the section actually is in the configuration file.
|
||||
/// </summary>
|
||||
protected bool IsPresent { get { return ElementInformation.IsPresent; } }
|
||||
|
||||
/// <summary>
|
||||
/// Resets settings that were set programmatically, to their initial values.
|
||||
/// </summary>
|
||||
/// <remarks>>To be used in unit tests.</remarks>
|
||||
internal protected virtual void ResetSection()
|
||||
{ }
|
||||
}
|
||||
}
|
||||
@@ -6,11 +6,9 @@ using System.Threading;
|
||||
using System.Web;
|
||||
using System.Web.Caching;
|
||||
using System.Xml;
|
||||
using System.Configuration;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
|
||||
namespace Umbraco.Core.Configuration
|
||||
@@ -22,8 +20,6 @@ namespace Umbraco.Core.Configuration
|
||||
|
||||
//TODO: Re-enable logging !!!!
|
||||
|
||||
//TODO: We need to convert this to a real section, it's currently using HttpRuntime.Cache to detect cahnges, this is real poor, especially in a console app
|
||||
|
||||
/// <summary>
|
||||
/// The UmbracoSettings Class contains general settings information for the entire Umbraco instance based on information from the /config/umbracoSettings.config file
|
||||
/// </summary>
|
||||
@@ -56,14 +52,15 @@ namespace Umbraco.Core.Configuration
|
||||
/// <summary>
|
||||
/// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config)
|
||||
/// </summary>
|
||||
private static void ResetInternal()
|
||||
internal static void ResetSetters()
|
||||
{
|
||||
_addTrailingSlash = null;
|
||||
_forceSafeAliases = null;
|
||||
_useLegacySchema = null;
|
||||
_useDomainPrefixes = null;
|
||||
_umbracoLibraryCacheDuration = null;
|
||||
SettingsFilePath = null;
|
||||
_trySkipIisCustomErrors = null;
|
||||
SettingsFilePath = null;
|
||||
}
|
||||
|
||||
internal const string TempFriendlyXmlChildContainerNodename = ""; // "children";
|
||||
@@ -506,7 +503,7 @@ namespace Umbraco.Core.Configuration
|
||||
private static IEnumerable<RazorDataTypeModelStaticMappingItem> _razorDataTypeModelStaticMapping;
|
||||
private static readonly ReaderWriterLockSlim Lock = new ReaderWriterLockSlim();
|
||||
|
||||
internal static IEnumerable<RazorDataTypeModelStaticMappingItem> RazorDataTypeModelStaticMapping
|
||||
public static IEnumerable<RazorDataTypeModelStaticMappingItem> RazorDataTypeModelStaticMapping
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -655,23 +652,36 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
|
||||
private static bool? _trySkipIisCustomErrors;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether to try to skip IIS custom errors.
|
||||
/// Gets or sets a value indicating where to try to skip IIS custom errors.
|
||||
/// </summary>
|
||||
[UmbracoWillObsolete("Use UmbracoSettings.For<WebRouting>.TrySkipIisCustomErrors instead.")]
|
||||
internal static bool TrySkipIisCustomErrors
|
||||
public static bool TrySkipIisCustomErrors
|
||||
{
|
||||
get { return GetKeyValue("/settings/web.routing/@trySkipIisCustomErrors", false); }
|
||||
get
|
||||
{
|
||||
// default: false
|
||||
return _trySkipIisCustomErrors ?? GetKeyValue("/settings/web.routing/@trySkipIisCustomErrors", false);
|
||||
}
|
||||
internal set
|
||||
{
|
||||
// used for unit testing
|
||||
_trySkipIisCustomErrors = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether internal redirect preserves the template.
|
||||
/// File types that will not be allowed to be uploaded via the content/media upload control
|
||||
/// </summary>
|
||||
[UmbracoWillObsolete("Use UmbracoSettings.For<WebRouting>.InternalRedirectPerservesTemplate instead.")]
|
||||
internal static bool InternalRedirectPreservesTemplate
|
||||
public static IEnumerable<string> DisallowedUploadFiles
|
||||
{
|
||||
get { return GetKeyValue("/settings/web.routing/@internalRedirectPreservesTemplate", false); }
|
||||
}
|
||||
get
|
||||
{
|
||||
var val = GetKey("/settings/content/disallowedUploadFiles");
|
||||
return val.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the allowed image file types.
|
||||
@@ -1216,12 +1226,6 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
return _defaultRenderingEngine.Value;
|
||||
}
|
||||
//internal set
|
||||
//{
|
||||
// _defaultRenderingEngine = value;
|
||||
// var node = UmbracoSettingsXmlDoc.DocumentElement.SelectSingleNode("/settings/templates/defaultRenderingEngine");
|
||||
// node.InnerText = value.ToString();
|
||||
//}
|
||||
}
|
||||
|
||||
private static MacroErrorBehaviour? _macroErrorBehaviour;
|
||||
@@ -1477,80 +1481,6 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region Extensible settings
|
||||
|
||||
/// <summary>
|
||||
/// Resets settings that were set programmatically, to their initial values.
|
||||
/// </summary>
|
||||
/// <remarks>To be used in unit tests.</remarks>
|
||||
internal static void Reset()
|
||||
{
|
||||
ResetInternal();
|
||||
|
||||
using (new WriteLock(SectionsLock))
|
||||
{
|
||||
foreach (var section in Sections.Values)
|
||||
section.ResetSection();
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly ReaderWriterLockSlim SectionsLock = new ReaderWriterLockSlim();
|
||||
private static readonly Dictionary<Type, UmbracoConfigurationSection> Sections = new Dictionary<Type, UmbracoConfigurationSection>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the specified UmbracoConfigurationSection.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the UmbracoConfigurationSectiont.</typeparam>
|
||||
/// <returns>The UmbracoConfigurationSection of the specified type.</returns>
|
||||
internal static T For<T>()
|
||||
where T : UmbracoConfigurationSection, new()
|
||||
{
|
||||
var sectionType = typeof (T);
|
||||
using (new WriteLock(SectionsLock))
|
||||
{
|
||||
if (Sections.ContainsKey(sectionType)) return Sections[sectionType] as T;
|
||||
|
||||
var attr = sectionType.GetCustomAttribute<ConfigurationKeyAttribute>(false);
|
||||
if (attr == null)
|
||||
throw new InvalidOperationException(string.Format("Type \"{0}\" is missing attribute ConfigurationKeyAttribute.", sectionType.FullName));
|
||||
|
||||
var sectionKey = attr.ConfigurationKey;
|
||||
if (string.IsNullOrWhiteSpace(sectionKey))
|
||||
throw new InvalidOperationException(string.Format("Type \"{0}\" ConfigurationKeyAttribute value is null or empty.", sectionType.FullName));
|
||||
|
||||
var section = GetSection(sectionType, sectionKey);
|
||||
|
||||
Sections[sectionType] = section;
|
||||
return section as T;
|
||||
}
|
||||
}
|
||||
|
||||
private static UmbracoConfigurationSection GetSection(Type sectionType, string key)
|
||||
{
|
||||
if (!sectionType.Inherits<UmbracoConfigurationSection>())
|
||||
throw new ArgumentException(string.Format(
|
||||
"Type \"{0}\" does not inherit from UmbracoConfigurationSection.", sectionType.FullName), "sectionType");
|
||||
|
||||
var section = ConfigurationManager.GetSection(key);
|
||||
|
||||
if (section != null && section.GetType() != sectionType)
|
||||
throw new InvalidCastException(string.Format("Section at key \"{0}\" is of type \"{1}\" and not \"{2}\".",
|
||||
key, section.GetType().FullName, sectionType.FullName));
|
||||
|
||||
if (section != null) return section as UmbracoConfigurationSection;
|
||||
|
||||
section = Activator.CreateInstance(sectionType) as UmbracoConfigurationSection;
|
||||
|
||||
if (section == null)
|
||||
throw new NullReferenceException(string.Format(
|
||||
"Activator failed to create an instance of type \"{0}\" for key\"{1}\" and returned null.",
|
||||
sectionType.FullName, key));
|
||||
|
||||
return section as UmbracoConfigurationSection;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
public class UmbracoVersion
|
||||
{
|
||||
private static readonly Version Version = new Version("6.1.0");
|
||||
private static readonly Version Version = new Version("6.0.4");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current version of Umbraco.
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the version comment (like beta or RC).
|
||||
/// </summary>
|
||||
/// <value>The version comment.</value>
|
||||
public static string CurrentComment { get { return "beta"; } }
|
||||
public static string CurrentComment { get { return ""; } }
|
||||
|
||||
// Get the version of the umbraco.dll by looking at a class in that dll
|
||||
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the alias identifiers for Umbraco's core application sections.
|
||||
/// </summary>
|
||||
public static class Applications
|
||||
{
|
||||
/// <summary>
|
||||
/// Application alias for the content section.
|
||||
/// </summary>
|
||||
public const string Content = "content";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the developer section.
|
||||
/// </summary>
|
||||
public const string Developer = "developer";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the media section.
|
||||
/// </summary>
|
||||
public const string Media = "media";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the members section.
|
||||
/// </summary>
|
||||
public const string Members = "member";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the settings section.
|
||||
/// </summary>
|
||||
public const string Settings = "settings";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the translation section.
|
||||
/// </summary>
|
||||
public const string Translation = "translation";
|
||||
|
||||
/// <summary>
|
||||
/// Application alias for the users section.
|
||||
/// </summary>
|
||||
public const string Users = "users";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for property-type alias conventions that are used within the Umbraco core.
|
||||
/// </summary>
|
||||
public static class Conventions
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants for Umbraco Content property aliases.
|
||||
/// </summary>
|
||||
public static class Content
|
||||
{
|
||||
/// <summary>
|
||||
/// Property alias for the Content's Url (internal) redirect.
|
||||
/// </summary>
|
||||
public const string InternalRedirectId = "umbracoInternalRedirectId";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Content's navigational hide, (not actually used in core code).
|
||||
/// </summary>
|
||||
public const string NaviHide = "umbracoNaviHide";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Content's Url redirect.
|
||||
/// </summary>
|
||||
public const string Redirect = "umbracoRedirect";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Content's Url alias.
|
||||
/// </summary>
|
||||
public const string UrlAlias = "umbracoUrlAlias";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Content's Url name.
|
||||
/// </summary>
|
||||
public const string UrlName = "umbracoUrlName";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco Media property aliases.
|
||||
/// </summary>
|
||||
public static class Media
|
||||
{
|
||||
/// <summary>
|
||||
/// Property alias for the Media's file name.
|
||||
/// </summary>
|
||||
public const string File = "umbracoFile";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Media's width.
|
||||
/// </summary>
|
||||
public const string Width = "umbracoWidth";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Media's height.
|
||||
/// </summary>
|
||||
public const string Height = "umbracoHeight";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Media's file size (in bytes).
|
||||
/// </summary>
|
||||
public const string Bytes = "umbracoBytes";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for the Media's file extension.
|
||||
/// </summary>
|
||||
public const string Extension = "umbracoExtension";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the alias identifiers for Umbraco media types.
|
||||
/// </summary>
|
||||
public static class MediaTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// MediaType alias for a file.
|
||||
/// </summary>
|
||||
public const string File = "File";
|
||||
|
||||
/// <summary>
|
||||
/// MediaType alias for a folder.
|
||||
/// </summary>
|
||||
public const string Folder = "Folder";
|
||||
|
||||
/// <summary>
|
||||
/// MediaType alias for an image.
|
||||
/// </summary>
|
||||
public const string Image = "Image";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco URLs/Querystrings.
|
||||
/// </summary>
|
||||
public static class Url
|
||||
{
|
||||
/// <summary>
|
||||
/// Querystring parameter name used for Umbraco's alternative template functionality.
|
||||
/// </summary>
|
||||
public const string AltTemplate = "altTemplate";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for Umbraco object types as constants for easy centralized access/management.
|
||||
/// </summary>
|
||||
public static class ObjectTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// Guid for a Content Item object.
|
||||
/// </summary>
|
||||
public const string ContentItem = "10E2B09F-C28B-476D-B77A-AA686435E44A";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Content Item Type object.
|
||||
/// </summary>
|
||||
public const string ContentItemType = "7A333C54-6F43-40A4-86A2-18688DC7E532";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Content Recycle Bin.
|
||||
/// </summary>
|
||||
public const string ContentRecycleBin = "01BB7FF2-24DC-4C0C-95A2-C24EF72BBAC8";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a DataType object.
|
||||
/// </summary>
|
||||
public const string DataType = "30A2A501-1978-4DDB-A57B-F7EFED43BA3C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Document object.
|
||||
/// </summary>
|
||||
public const string Document = "C66BA18E-EAF3-4CFF-8A22-41B16D66A972";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Document Type object.
|
||||
/// </summary>
|
||||
public const string DocumentType = "A2CB7800-F571-4787-9638-BC48539A0EFB";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Media object.
|
||||
/// </summary>
|
||||
public const string Media = "B796F64C-1F99-4FFB-B886-4BF4BC011A9C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Media Recycle Bin.
|
||||
/// </summary>
|
||||
public const string MediaRecycleBin = "CF3D8E34-1C1C-41e9-AE56-878B57B32113";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Media Type object.
|
||||
/// </summary>
|
||||
public const string MediaType = "4EA4382B-2F5A-4C2B-9587-AE9B3CF3602E";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member object.
|
||||
/// </summary>
|
||||
public const string Member = "39EB0F98-B348-42A1-8662-E7EB18487560";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member Group object.
|
||||
/// </summary>
|
||||
public const string MemberGroup = "366E63B9-880F-4E13-A61C-98069B029728";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Member Type object.
|
||||
/// </summary>
|
||||
public const string MemberType = "9B5416FB-E72F-45A9-A07B-5A9A2709CE43";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Stylesheet object.
|
||||
/// </summary>
|
||||
public const string Stylesheet = "9F68DA4F-A3A8-44C2-8226-DCBD125E4840";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the System Root.
|
||||
/// </summary>
|
||||
public const string SystemRoot = "EA7D8624-4CFE-4578-A871-24AA946BF34D";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for a Template object.
|
||||
/// </summary>
|
||||
public const string Template = "6FBDE604-4178-42CE-A10B-8A2600A2F07D";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for Umbraco Property Editors as constants for easy centralized access/management.
|
||||
/// </summary>
|
||||
public static class PropertyEditors
|
||||
{
|
||||
/// <summary>
|
||||
/// Guid for the Checkbox list datatype.
|
||||
/// </summary>
|
||||
public const string CheckBoxList = "B4471851-82B6-4C75-AFA4-39FA9C6A75E9";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Color Picker datatype.
|
||||
/// </summary>
|
||||
public const string ColorPicker = "F8D60F68-EC59-4974-B43B-C46EB5677985";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Content Picker datatype.
|
||||
/// </summary>
|
||||
public const string ContentPicker = "158AA029-24ED-4948-939E-C3DA209E5FBA";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Date datatype.
|
||||
/// </summary>
|
||||
public const string Date = "23E93522-3200-44E2-9F29-E61A6FCBB79A";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Date/Time datatype.
|
||||
/// </summary>
|
||||
public const string DateTime = "B6FB1622-AFA5-4BBF-A3CC-D9672A442222";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Dictionary Picker datatype.
|
||||
/// </summary>
|
||||
public const string DictionaryPicker = "17B70066-F764-407D-AB05-3717F1E1C513";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Dropdown list datatype.
|
||||
/// </summary>
|
||||
public const string DropDownList = "A74EA9C9-8E18-4D2A-8CF6-73C6206C5DA6";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Dropdown list multiple datatype.
|
||||
/// </summary>
|
||||
public const string DropDownListMultiple = "928639ED-9C73-4028-920C-1E55DBB68783";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Dropdown list multiple, publish keys datatype.
|
||||
/// </summary>
|
||||
public const string DropdownlistMultiplePublishKeys = "928639AA-9C73-4028-920C-1E55DBB68783";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Dropdown list, publishing keys datatype.
|
||||
/// </summary>
|
||||
public const string DropdownlistPublishingKeys = "A74EA9E1-8E18-4D2A-8CF6-73C6206C5DA6";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Folder browser datatype.
|
||||
/// </summary>
|
||||
public const string FolderBrowser = "CCCD4AE9-F399-4ED2-8038-2E88D19E810C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Image Cropper datatype.
|
||||
/// </summary>
|
||||
public const string ImageCropper = "7A2D436C-34C2-410F-898F-4A23B3D79F54";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Integer datatype.
|
||||
/// </summary>
|
||||
public const string Integer = "1413AFCB-D19A-4173-8E9A-68288D2A73B8";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Macro Container datatype.
|
||||
/// </summary>
|
||||
public const string MacroContainer = "474FCFF8-9D2D-11DE-ABC6-AD7A56D89593";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Media Picker datatype.
|
||||
/// </summary>
|
||||
public const string MediaPicker = "EAD69342-F06D-4253-83AC-28000225583B";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Member Picker datatype.
|
||||
/// </summary>
|
||||
public const string MemberPicker = "39F533E4-0551-4505-A64B-E0425C5CE775";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Multi-Node Tree Picker datatype
|
||||
/// </summary>
|
||||
public const string MultiNodeTreePicker = "7E062C13-7C41-4AD9-B389-41D88AEEF87C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Multiple Textstring datatype.
|
||||
/// </summary>
|
||||
public const string MultipleTextstring = "5359AD0B-06CC-4182-92BD-0A9117448D3F";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the No edit datatype.
|
||||
/// </summary>
|
||||
public const string NoEdit = "6C738306-4C17-4D88-B9BD-6546F3771597";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Picker Relations datatype.
|
||||
/// </summary>
|
||||
public const string PickerRelations = "83396FF2-2E39-4A90-9066-17F5F3989374";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Radiobutton list datatype.
|
||||
/// </summary>
|
||||
public const string RadioButtonList = "A52C7C1C-C330-476E-8605-D63D3B84B6A6";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Related Links datatype.
|
||||
/// </summary>
|
||||
public const string RelatedLinks = "71B8AD1A-8DC2-425C-B6B8-FAA158075E63";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Slider datatype.
|
||||
/// </summary>
|
||||
public const string Slider = "29E790E6-26B3-438A-B21F-908663A0B19E";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Tags datatype.
|
||||
/// </summary>
|
||||
public const string Tags = "4023E540-92F5-11DD-AD8B-0800200C9A66";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Textbox datatype.
|
||||
/// </summary>
|
||||
public const string Textbox = "EC15C1E5-9D90-422A-AA52-4F7622C63BEA";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Textbox multiple datatype.
|
||||
/// </summary>
|
||||
public const string TextboxMultiple = "67DB8357-EF57-493E-91AC-936D305E0F2A";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the TinyMCE v3 wysiwyg datatype.
|
||||
/// </summary>
|
||||
public const string TinyMCEv3 = "5E9B75AE-FACE-41C8-B47E-5F4B0FD82F83";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the TinyMCE wysiwyg (deprecated, upgrade to tinymce v3!) datatype.
|
||||
/// </summary>
|
||||
public const string TinyMCE = "83722133-F80C-4273-BDB6-1BEFAA04A612";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the True/False (Ja/Nej) datatype.
|
||||
/// </summary>
|
||||
public const string TrueFalse = "38B352C1-E9F8-4FD8-9324-9A2EAB06D97A";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Ultimate Picker datatype.
|
||||
/// </summary>
|
||||
public const string UltimatePicker = "CDBF0B5D-5CB2-445F-BC12-FCAAEC07CF2C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the UltraSimpleEditor datatype.
|
||||
/// </summary>
|
||||
public const string UltraSimpleEditor = "60B7DABF-99CD-41EB-B8E9-4D2E669BBDE9";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Umbraco Usercontrol Wrapper datatype.
|
||||
/// </summary>
|
||||
public const string UmbracoUserControlWrapper = "D15E1281-E456-4B24-AA86-1DDA3E4299D5";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the Upload field datatype.
|
||||
/// </summary>
|
||||
public const string UploadField = "5032A6E6-69E3-491D-BB28-CD31CD11086C";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the XPath CheckBoxList datatype.
|
||||
/// </summary>
|
||||
public const string XPathCheckBoxList = "34451D92-D270-49BA-8C7F-EE55BFEEE1CB";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for the XPath DropDownList datatype.
|
||||
/// </summary>
|
||||
public const string XPathDropDownList = "173A96AE-00ED-4A7C-9F76-4B53D4A0A1B9";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the identifiers for Umbraco system nodes.
|
||||
/// </summary>
|
||||
public static class System
|
||||
{
|
||||
/// <summary>
|
||||
/// The integer identifier for global system root node.
|
||||
/// </summary>
|
||||
public const int Root = -1;
|
||||
|
||||
/// <summary>
|
||||
/// The integer identifier for content's recycle bin.
|
||||
/// </summary>
|
||||
public const int RecycleBinContent = -20;
|
||||
|
||||
/// <summary>
|
||||
/// The integer identifier for media's recycle bin.
|
||||
/// </summary>
|
||||
public const int RecycleBinMedia = -21;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Constants all the identifiers within the Umbraco core.
|
||||
/// </summary>
|
||||
public static partial class Constants
|
||||
{
|
||||
// generic constants can go here
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,7 @@ using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Macros;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Sync;
|
||||
using Umbraco.Core.Strings;
|
||||
using MigrationsVersionFourNineZero = Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourNineZero;
|
||||
|
||||
namespace Umbraco.Core
|
||||
@@ -109,8 +106,6 @@ namespace Umbraco.Core
|
||||
{
|
||||
CanResolveBeforeFrozen = true
|
||||
};
|
||||
//add custom types here that are internal
|
||||
ApplicationEventsResolver.Current.AddType<PublishedContentHelper>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -180,25 +175,12 @@ namespace Umbraco.Core
|
||||
{
|
||||
Resolution.Freeze();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create the resolvers
|
||||
/// </summary>
|
||||
protected virtual void InitializeResolvers()
|
||||
{
|
||||
//by default we'll use the standard configuration based sync
|
||||
ServerRegistrarResolver.Current = new ServerRegistrarResolver(
|
||||
new ConfigServerRegistrar());
|
||||
|
||||
//by default (outside of the web) we'll use the default server messenger without
|
||||
//supplying a username/password, this will automatically disable distributed calls
|
||||
// .. we'll override this in the WebBootManager
|
||||
ServerMessengerResolver.Current = new ServerMessengerResolver(
|
||||
new DefaultServerMessenger());
|
||||
|
||||
MappingResolver.Current = new MappingResolver(
|
||||
() => PluginManager.Current.ResolveAssignedMapperTypes());
|
||||
|
||||
RepositoryResolver.Current = new RepositoryResolver(
|
||||
new RepositoryFactory());
|
||||
|
||||
@@ -226,11 +208,27 @@ namespace Umbraco.Core
|
||||
MacroPropertyTypeResolver.Current = new MacroPropertyTypeResolver(
|
||||
PluginManager.Current.ResolveMacroPropertyTypes());
|
||||
|
||||
//the database migration objects
|
||||
MigrationResolver.Current = new MigrationResolver(
|
||||
() => PluginManager.Current.ResolveMigrationTypes());
|
||||
//TODO: Y U NO WORK?
|
||||
//MigrationResolver.Current = new MigrationResolver(
|
||||
// PluginManager.Current.ResolveMigrationTypes());
|
||||
|
||||
|
||||
//the database migration objects
|
||||
MigrationResolver.Current = new MigrationResolver(new List<Type>
|
||||
{
|
||||
typeof (MigrationsVersionFourNineZero.RemoveUmbracoAppConstraints),
|
||||
typeof (DeleteAppTables),
|
||||
typeof (EnsureAppsTreesUpdated),
|
||||
typeof (MoveMasterContentTypeData),
|
||||
typeof (NewCmsContentType2ContentTypeTable),
|
||||
typeof (RemoveMasterContentTypeColumn),
|
||||
typeof (RenameCmsTabTable),
|
||||
typeof (RenameTabIdColumn),
|
||||
typeof (UpdateCmsContentTypeAllowedContentTypeTable),
|
||||
typeof (UpdateCmsContentTypeTable),
|
||||
typeof (UpdateCmsContentVersionTable),
|
||||
typeof (UpdateCmsPropertyTypeGroupTable),
|
||||
typeof (UpdatePropertyTypesAndGroups)
|
||||
});
|
||||
|
||||
PropertyEditorValueConvertersResolver.Current = new PropertyEditorValueConvertersResolver(
|
||||
PluginManager.Current.ResolvePropertyEditorValueConverters());
|
||||
@@ -238,18 +236,6 @@ namespace Umbraco.Core
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<DatePickerPropertyEditorValueConverter>();
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<TinyMcePropertyEditorValueConverter>();
|
||||
PropertyEditorValueConvertersResolver.Current.AddType<YesNoPropertyEditorValueConverter>();
|
||||
|
||||
// this is how we'd switch over to DefaultShortStringHelper _and_ still use
|
||||
// UmbracoSettings UrlReplaceCharacters...
|
||||
//ShortStringHelperResolver.Current = new ShortStringHelperResolver(
|
||||
// new DefaultShortStringHelper().WithConfig(DefaultShortStringHelper.ApplyUrlReplaceCharacters));
|
||||
|
||||
// use the Legacy one for now
|
||||
ShortStringHelperResolver.Current = new ShortStringHelperResolver(
|
||||
new LegacyShortStringHelper());
|
||||
|
||||
UrlSegmentProviderResolver.Current = new UrlSegmentProviderResolver(
|
||||
typeof (DefaultUrlSegmentProvider));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Umbraco.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
EnsureIsInitialized();
|
||||
EnsureIdsAreTracked();
|
||||
return Values;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// Custom IApplicationStartupHandler that auto subscribes to the applications events
|
||||
/// </summary>
|
||||
public interface IApplicationEventHandler : IApplicationStartupHandler
|
||||
|
||||
@@ -137,42 +137,25 @@ namespace Umbraco.Core.IO
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the current filepath matches a directory where the user is allowed to edit a file.
|
||||
/// Validates if the current filepath matches a directory where the user is allowed to edit a file
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validDir">The valid directory.</param>
|
||||
/// <returns>A value indicating whether the filepath is valid.</returns>
|
||||
internal static bool VerifyEditPath(string filePath, string validDir)
|
||||
/// <param name="filePath">filepath </param>
|
||||
/// <param name="validDir"></param>
|
||||
/// <returns>true if valid, throws a FileSecurityException if not</returns>
|
||||
internal static bool ValidateEditPath(string filePath, string validDir)
|
||||
{
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
filePath = MapPath(filePath);
|
||||
if (!validDir.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
validDir = MapPath(validDir);
|
||||
|
||||
return filePath.StartsWith(validDir);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the current filepath matches a directory where the user is allowed to edit a file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validDir">The valid directory.</param>
|
||||
/// <returns>True, if the filepath is valid, else an exception is thrown.</returns>
|
||||
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
|
||||
internal static bool ValidateEditPath(string filePath, string validDir)
|
||||
{
|
||||
if (!VerifyEditPath(filePath, validDir))
|
||||
if (!filePath.StartsWith(validDir))
|
||||
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the current filepath matches one of several directories where the user is allowed to edit a file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validDirs">The valid directories.</param>
|
||||
/// <returns>A value indicating whether the filepath is valid.</returns>
|
||||
internal static bool VerifyEditPath(string filePath, IEnumerable<string> validDirs)
|
||||
internal static bool ValidateEditPath(string filePath, IEnumerable<string> validDirs)
|
||||
{
|
||||
foreach (var dir in validDirs)
|
||||
{
|
||||
@@ -186,49 +169,19 @@ namespace Umbraco.Core.IO
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the current filepath matches one of several directories where the user is allowed to edit a file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validDirs">The valid directories.</param>
|
||||
/// <returns>True, if the filepath is valid, else an exception is thrown.</returns>
|
||||
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
|
||||
internal static bool ValidateEditPath(string filePath, IEnumerable<string> validDirs)
|
||||
{
|
||||
if (!VerifyEditPath(filePath, validDirs))
|
||||
throw new FileSecurityException(String.Format("The filepath '{0}' is not within an allowed directory for this type of files", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the current filepath has one of several authorized extensions.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validFileExtensions">The valid extensions.</param>
|
||||
/// <returns>A value indicating whether the filepath is valid.</returns>
|
||||
internal static bool VerifyFileExtension(string filePath, List<string> validFileExtensions)
|
||||
internal static bool ValidateFileExtension(string filePath, List<string> validFileExtensions)
|
||||
{
|
||||
if (!filePath.StartsWith(MapPath(SystemDirectories.Root)))
|
||||
filePath = MapPath(filePath);
|
||||
var f = new FileInfo(filePath);
|
||||
|
||||
return validFileExtensions.Contains(f.Extension.Substring(1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates that the current filepath has one of several authorized extensions.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The filepath to validate.</param>
|
||||
/// <param name="validFileExtensions">The valid extensions.</param>
|
||||
/// <returns>True, if the filepath is valid, else an exception is thrown.</returns>
|
||||
/// <exception cref="FileSecurityException">The filepath is invalid.</exception>
|
||||
internal static bool ValidateFileExtension(string filePath, List<string> validFileExtensions)
|
||||
{
|
||||
if (!VerifyFileExtension(filePath, validFileExtensions))
|
||||
|
||||
if (!validFileExtensions.Contains(f.Extension.Substring(1)))
|
||||
throw new FileSecurityException(String.Format("The extension for the current file '{0}' is not of an allowed type for this editor. This is typically controlled from either the installed MacroEngines or based on configuration in /config/umbracoSettings.config", filePath.Replace(MapPath(SystemDirectories.Root), "")));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -263,8 +216,55 @@ namespace Umbraco.Core.IO
|
||||
/// <returns>A safe filename without any path specific chars.</returns>
|
||||
internal static string SafeFileName(string filePath)
|
||||
{
|
||||
// use string extensions
|
||||
return filePath.ToSafeFileName();
|
||||
if (String.IsNullOrEmpty(filePath))
|
||||
return String.Empty;
|
||||
|
||||
if (!String.IsNullOrWhiteSpace(filePath))
|
||||
{
|
||||
foreach (var character in Path.GetInvalidFileNameChars())
|
||||
{
|
||||
filePath = filePath.Replace(character, '-');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
filePath = String.Empty;
|
||||
}
|
||||
|
||||
//Break up the file in name and extension before applying the UrlReplaceCharacters
|
||||
var fileNamePart = filePath.Substring(0, filePath.LastIndexOf('.'));
|
||||
var ext = filePath.Substring(filePath.LastIndexOf('.'));
|
||||
|
||||
//Because the file usually is downloadable as well we check characters against 'UmbracoSettings.UrlReplaceCharacters'
|
||||
XmlNode replaceChars = UmbracoSettings.UrlReplaceCharacters;
|
||||
foreach (XmlNode n in replaceChars.SelectNodes("char"))
|
||||
{
|
||||
if (n.Attributes.GetNamedItem("org") != null && n.Attributes.GetNamedItem("org").Value != "")
|
||||
fileNamePart = fileNamePart.Replace(n.Attributes.GetNamedItem("org").Value, XmlHelper.GetNodeValue(n));
|
||||
}
|
||||
|
||||
filePath = string.Concat(fileNamePart, ext);
|
||||
|
||||
// Adapted from: http://stackoverflow.com/a/4827510/5018
|
||||
// Combined both Reserved Characters and Character Data
|
||||
// from http://en.wikipedia.org/wiki/Percent-encoding
|
||||
var stringBuilder = new StringBuilder();
|
||||
|
||||
const string reservedCharacters = "!*'();:@&=+$,/?%#[]-~{}\"<>\\^`| ";
|
||||
|
||||
foreach (var character in filePath)
|
||||
{
|
||||
if (reservedCharacters.IndexOf(character) == -1)
|
||||
stringBuilder.Append(character);
|
||||
else
|
||||
stringBuilder.Append("-");
|
||||
}
|
||||
|
||||
// Remove repeating dashes
|
||||
// From: http://stackoverflow.com/questions/5111967/regex-to-remove-a-specific-repeated-character
|
||||
var reducedString = Regex.Replace(stringBuilder.ToString(), "-+", "-");
|
||||
|
||||
return reducedString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -103,11 +101,8 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_template = value;
|
||||
return _template;
|
||||
}, _template, TemplateSelector);
|
||||
_template = value;
|
||||
OnPropertyChanged(TemplateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,11 +140,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _published; }
|
||||
internal set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_published = value;
|
||||
return _published;
|
||||
}, _published, PublishedSelector);
|
||||
_published = value;
|
||||
OnPropertyChanged(PublishedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,11 +157,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _language; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_language = value;
|
||||
return _language;
|
||||
}, _language, LanguageSelector);
|
||||
_language = value;
|
||||
OnPropertyChanged(LanguageSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,11 +171,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _releaseDate; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_releaseDate = value;
|
||||
return _releaseDate;
|
||||
}, _releaseDate, ReleaseDateSelector);
|
||||
_releaseDate = value;
|
||||
OnPropertyChanged(ReleaseDateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,11 +185,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _expireDate; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_expireDate = value;
|
||||
return _expireDate;
|
||||
}, _expireDate, ExpireDateSelector);
|
||||
_expireDate = value;
|
||||
OnPropertyChanged(ExpireDateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,11 +199,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _writer; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_writer = value;
|
||||
return _writer;
|
||||
}, _writer, WriterSelector);
|
||||
_writer = value;
|
||||
OnPropertyChanged(WriterSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,11 +215,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _nodeName; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_nodeName = value;
|
||||
return _nodeName;
|
||||
}, _nodeName, NodeNameSelector);
|
||||
_nodeName = value;
|
||||
OnPropertyChanged(NodeNameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
@@ -14,7 +13,6 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Represents an abstract class for base Content properties and methods
|
||||
/// </summary>
|
||||
[DebuggerDisplay("Id: {Id}, Name: {Name}, ContentType: {ContentTypeBase.Alias}")]
|
||||
public abstract class ContentBase : Entity, IContentBase
|
||||
{
|
||||
protected IContentTypeComposition ContentTypeBase;
|
||||
@@ -120,11 +118,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
_name = value;
|
||||
OnPropertyChanged(NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,11 +132,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
_sortOrder = value;
|
||||
OnPropertyChanged(SortOrderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,11 +146,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _level; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_level = value;
|
||||
return _level;
|
||||
}, _level, LevelSelector);
|
||||
_level = value;
|
||||
OnPropertyChanged(LevelSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,11 +160,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _path; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_path = value;
|
||||
return _path;
|
||||
}, _path, PathSelector);
|
||||
_path = value;
|
||||
OnPropertyChanged(PathSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,11 +174,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, CreatorIdSelector);
|
||||
_creatorId = value;
|
||||
OnPropertyChanged(CreatorIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,11 +190,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _trashed; }
|
||||
internal set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_trashed = value;
|
||||
return _trashed;
|
||||
}, _trashed, TrashedSelector);
|
||||
_trashed = value;
|
||||
OnPropertyChanged(TrashedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,11 +210,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _contentTypeId; }
|
||||
protected set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_contentTypeId = value;
|
||||
return _contentTypeId;
|
||||
}, _contentTypeId, DefaultContentTypeIdSelector);
|
||||
_contentTypeId = value;
|
||||
OnPropertyChanged(DefaultContentTypeIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
@@ -13,7 +12,6 @@ using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Media;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Strings;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
@@ -21,90 +19,6 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
public static class ContentExtensions
|
||||
{
|
||||
#region IContent
|
||||
/// <summary>
|
||||
/// Returns a list of the current contents ancestors, not including the content itself.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public static IEnumerable<IContent> Ancestors(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.ContentService.GetAncestors(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current contents children.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public static IEnumerable<IContent> Children(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.ContentService.GetChildren(content.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current contents descendants, not including the content itself.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <returns>An enumerable list of <see cref="IContent"/> objects</returns>
|
||||
public static IEnumerable<IContent> Descendants(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.ContentService.GetDescendants(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the parent of the current content.
|
||||
/// </summary>
|
||||
/// <param name="content">Current content</param>
|
||||
/// <returns>An <see cref="IContent"/> object</returns>
|
||||
public static IContent Parent(this IContent content)
|
||||
{
|
||||
return ApplicationContext.Current.Services.ContentService.GetById(content.ParentId);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IMedia
|
||||
/// <summary>
|
||||
/// Returns a list of the current medias ancestors, not including the media itself.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public static IEnumerable<IMedia> Ancestors(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.MediaService.GetAncestors(media);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current medias children.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public static IEnumerable<IMedia> Children(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.MediaService.GetChildren(media.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the current medias descendants, not including the media itself.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <returns>An enumerable list of <see cref="IMedia"/> objects</returns>
|
||||
public static IEnumerable<IMedia> Descendants(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.MediaService.GetDescendants(media);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the parent of the current media.
|
||||
/// </summary>
|
||||
/// <param name="media">Current media</param>
|
||||
/// <returns>An <see cref="IMedia"/> object</returns>
|
||||
public static IMedia Parent(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.MediaService.GetById(media.ParentId);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Set property values by alias with an annonymous object
|
||||
/// </summary>
|
||||
@@ -251,7 +165,7 @@ namespace Umbraco.Core.Models
|
||||
var thumbUrl = Resize(fs, fileName, extension, 100, "thumb");
|
||||
|
||||
//Look up Prevalues for this upload datatype - if it is an upload datatype
|
||||
var uploadFieldId = new Guid(Constants.PropertyEditors.UploadField);
|
||||
var uploadFieldId = new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c");
|
||||
if (property.PropertyType.DataTypeId == uploadFieldId)
|
||||
{
|
||||
//Get Prevalues by the DataType's Id: property.PropertyType.DataTypeId
|
||||
@@ -423,16 +337,8 @@ namespace Umbraco.Core.Models
|
||||
return new Tuple<int, int, string>(widthTh, heightTh, newFileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IProfile"/> for the Creator of this media item.
|
||||
/// </summary>
|
||||
public static IProfile GetCreatorProfile(this IMedia media)
|
||||
{
|
||||
return ApplicationContext.Current.Services.UserService.GetProfileById(media.CreatorId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IProfile"/> for the Creator of this content item.
|
||||
/// Gets the <see cref="IProfile"/> for the Creator of this content/media item.
|
||||
/// </summary>
|
||||
public static IProfile GetCreatorProfile(this IContentBase content)
|
||||
{
|
||||
@@ -460,47 +366,6 @@ namespace Umbraco.Core.Models
|
||||
return ApplicationContext.Current.Services.ContentService.HasPublishedVersion(content.Id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the full xml representation for the <see cref="IContent"/> object and all of it's descendants
|
||||
/// </summary>
|
||||
/// <param name="content"><see cref="IContent"/> to generate xml for</param>
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
internal static XElement ToDeepXml(this IContent content)
|
||||
{
|
||||
var xml = content.ToXml();
|
||||
|
||||
var descendants = content.Descendants().ToArray();
|
||||
var currentChildren = descendants.Where(x => x.ParentId == content.Id);
|
||||
AddChildXml(descendants, currentChildren, xml);
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by ToDeepXml to recursively add children
|
||||
/// </summary>
|
||||
/// <param name="originalDescendants"></param>
|
||||
/// <param name="currentChildren"></param>
|
||||
/// <param name="currentXml"></param>
|
||||
private static void AddChildXml(
|
||||
IContent[] originalDescendants,
|
||||
IEnumerable<IContent> currentChildren,
|
||||
XElement currentXml)
|
||||
{
|
||||
foreach (var child in currentChildren)
|
||||
{
|
||||
//add the child's xml
|
||||
var childXml = child.ToXml();
|
||||
currentXml.Add(childXml);
|
||||
//copy local (out of closure)
|
||||
var c = child;
|
||||
//get this item's children
|
||||
var children = originalDescendants.Where(x => x.ParentId == c.Id);
|
||||
//recurse and add it's children to the child xml element
|
||||
AddChildXml(originalDescendants, children, childXml);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the xml representation for the <see cref="IContent"/> object
|
||||
/// </summary>
|
||||
@@ -508,8 +373,8 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
public static XElement ToXml(this IContent content)
|
||||
{
|
||||
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
|
||||
var nodeName = UmbracoSettings.UseLegacyXmlSchema ? "node" : content.ContentType.Alias.ToSafeAliasWithForcingCheck();
|
||||
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
|
||||
var nodeName = UmbracoSettings.UseLegacyXmlSchema ? "node" : content.ContentType.Alias.ToSafeAliasWithForcingCheck();
|
||||
|
||||
var x = content.ToXml(nodeName);
|
||||
x.Add(new XAttribute("nodeType", content.ContentType.Id));
|
||||
@@ -557,10 +422,9 @@ namespace Umbraco.Core.Models
|
||||
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
|
||||
private static XElement ToXml(this IContentBase contentBase, string nodeName)
|
||||
{
|
||||
// note: that one will take care of umbracoUrlName
|
||||
var url = contentBase.GetUrlSegment();
|
||||
var niceUrl = contentBase.Name.FormatUrl().ToLower();
|
||||
|
||||
var xml = new XElement(nodeName,
|
||||
var xml = new XElement(nodeName,
|
||||
new XAttribute("id", contentBase.Id),
|
||||
new XAttribute("parentID", contentBase.Level > 1 ? contentBase.ParentId : -1),
|
||||
new XAttribute("level", contentBase.Level),
|
||||
@@ -569,15 +433,24 @@ namespace Umbraco.Core.Models
|
||||
new XAttribute("createDate", contentBase.CreateDate.ToString("s")),
|
||||
new XAttribute("updateDate", contentBase.UpdateDate.ToString("s")),
|
||||
new XAttribute("nodeName", contentBase.Name),
|
||||
new XAttribute("urlName", url),
|
||||
new XAttribute("urlName", niceUrl),//Format Url ?
|
||||
new XAttribute("path", contentBase.Path),
|
||||
new XAttribute("isDoc", ""));
|
||||
|
||||
foreach (var property in contentBase.Properties.Where(p => p != null))
|
||||
xml.Add(property.ToXml());
|
||||
foreach (var property in contentBase.Properties)
|
||||
{
|
||||
if (property == null) continue;
|
||||
|
||||
return xml;
|
||||
}
|
||||
xml.Add(property.ToXml());
|
||||
|
||||
//Check for umbracoUrlName convention
|
||||
if (property.Alias == "umbracoUrlName" && property.Value != null &&
|
||||
property.Value.ToString().Trim() != string.Empty)
|
||||
xml.SetAttributeValue("urlName", property.Value.ToString().FormatUrl().ToLower());
|
||||
}
|
||||
|
||||
return xml;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the xml representation for the <see cref="IContent"/> object
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -48,11 +47,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _defaultTemplate; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_defaultTemplate = value;
|
||||
return _defaultTemplate;
|
||||
}, _defaultTemplate, DefaultTemplateSelector);
|
||||
_defaultTemplate = value;
|
||||
OnPropertyChanged(DefaultTemplateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,11 +61,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _allowedTemplates; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_allowedTemplates = value;
|
||||
return _allowedTemplates;
|
||||
}, _allowedTemplates, AllowedTemplatesSelector);
|
||||
_allowedTemplates = value;
|
||||
OnPropertyChanged(AllowedTemplatesSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ namespace Umbraco.Core.Models
|
||||
private string _alias;
|
||||
private string _description;
|
||||
private int _sortOrder;
|
||||
private string _icon = "folder.png";
|
||||
private string _thumbnail = "folder.png";
|
||||
private string _icon;
|
||||
private string _thumbnail;
|
||||
private int _creatorId;
|
||||
private bool _allowedAsRoot;
|
||||
private bool _isContainer;
|
||||
@@ -31,8 +31,6 @@ namespace Umbraco.Core.Models
|
||||
private PropertyGroupCollection _propertyGroups;
|
||||
private PropertyTypeCollection _propertyTypes;
|
||||
private IEnumerable<ContentTypeSort> _allowedContentTypes;
|
||||
private bool _hasPropertyTypeBeenRemoved;
|
||||
|
||||
|
||||
protected ContentTypeBase(int parentId)
|
||||
{
|
||||
@@ -70,8 +68,6 @@ namespace Umbraco.Core.Models
|
||||
private static readonly PropertyInfo AllowedContentTypesSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, IEnumerable<ContentTypeSort>>(x => x.AllowedContentTypes);
|
||||
private static readonly PropertyInfo PropertyGroupCollectionSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, PropertyGroupCollection>(x => x.PropertyGroups);
|
||||
private static readonly PropertyInfo PropertyTypeCollectionSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, IEnumerable<PropertyType>>(x => x.PropertyTypes);
|
||||
private static readonly PropertyInfo HasPropertyTypeBeenRemovedSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, bool>(x => x.HasPropertyTypeBeenRemoved);
|
||||
|
||||
|
||||
protected void PropertyGroupsChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
@@ -115,11 +111,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
_name = value;
|
||||
OnPropertyChanged(NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,11 +125,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _level; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_level = value;
|
||||
return _level;
|
||||
}, _level, LevelSelector);
|
||||
_level = value;
|
||||
OnPropertyChanged(LevelSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,11 +139,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _path; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_path = value;
|
||||
return _path;
|
||||
}, _path, PathSelector);
|
||||
_path = value;
|
||||
OnPropertyChanged(PathSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,11 +153,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_alias = value.ToSafeAlias();
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
_alias = value.ToSafeAlias();
|
||||
OnPropertyChanged(AliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,11 +167,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _description; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_description = value;
|
||||
return _description;
|
||||
}, _description, DescriptionSelector);
|
||||
_description = value;
|
||||
OnPropertyChanged(DescriptionSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,11 +181,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
_sortOrder = value;
|
||||
OnPropertyChanged(SortOrderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,11 +195,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _icon; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_icon = value;
|
||||
return _icon;
|
||||
}, _icon, IconSelector);
|
||||
_icon = value;
|
||||
OnPropertyChanged(IconSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,11 +209,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _thumbnail; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_thumbnail = value;
|
||||
return _thumbnail;
|
||||
}, _thumbnail, ThumbnailSelector);
|
||||
_thumbnail = value;
|
||||
OnPropertyChanged(ThumbnailSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,11 +223,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, CreatorIdSelector);
|
||||
_creatorId = value;
|
||||
OnPropertyChanged(CreatorIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,11 +237,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _allowedAsRoot; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_allowedAsRoot = value;
|
||||
return _allowedAsRoot;
|
||||
}, _allowedAsRoot, AllowedAsRootSelector);
|
||||
_allowedAsRoot = value;
|
||||
OnPropertyChanged(AllowedAsRootSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,11 +254,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _isContainer; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_isContainer = value;
|
||||
return _isContainer;
|
||||
}, _isContainer, IsContainerSelector);
|
||||
_isContainer = value;
|
||||
OnPropertyChanged(IsContainerSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,11 +269,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _trashed; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_trashed = value;
|
||||
return _trashed;
|
||||
}, _trashed, TrashedSelector);
|
||||
_trashed = value;
|
||||
OnPropertyChanged(TrashedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,11 +283,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _allowedContentTypes; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_allowedContentTypes = value;
|
||||
return _allowedContentTypes;
|
||||
}, _allowedContentTypes, AllowedContentTypesSelector);
|
||||
_allowedContentTypes = value;
|
||||
OnPropertyChanged(AllowedContentTypesSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,24 +322,6 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A boolean flag indicating if a property type has been removed from this instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is currently (specifically) used in order to know that we need to refresh the content cache which
|
||||
/// needs to occur when a property has been removed from a content type
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
internal bool HasPropertyTypeBeenRemoved
|
||||
{
|
||||
get { return _hasPropertyTypeBeenRemoved; }
|
||||
private set
|
||||
{
|
||||
_hasPropertyTypeBeenRemoved = value;
|
||||
OnPropertyChanged(HasPropertyTypeBeenRemovedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a PropertyType with a given alias already exists
|
||||
/// </summary>
|
||||
@@ -457,15 +396,6 @@ namespace Umbraco.Core.Models
|
||||
/// <param name="propertyTypeAlias">Alias of the <see cref="PropertyType"/> to remove</param>
|
||||
public void RemovePropertyType(string propertyTypeAlias)
|
||||
{
|
||||
|
||||
//check if the property exist in one of our collections
|
||||
if (PropertyGroups.Any(group => group.PropertyTypes.Any(pt => pt.Alias == propertyTypeAlias))
|
||||
|| _propertyTypes.Any(x => x.Alias == propertyTypeAlias))
|
||||
{
|
||||
//set the flag that a property has been removed
|
||||
HasPropertyTypeBeenRemoved = true;
|
||||
}
|
||||
|
||||
foreach (var propertyGroup in PropertyGroups)
|
||||
{
|
||||
propertyGroup.PropertyTypes.RemoveItem(propertyTypeAlias);
|
||||
@@ -473,7 +403,7 @@ namespace Umbraco.Core.Models
|
||||
|
||||
if (_propertyTypes.Any(x => x.Alias == propertyTypeAlias))
|
||||
{
|
||||
_propertyTypes.RemoveItem(propertyTypeAlias);
|
||||
_propertyTypes.RemoveItem(propertyTypeAlias);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
internal static class ContentTypeExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Get all descendant content types
|
||||
/// </summary>
|
||||
/// <param name="contentType"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<IContentTypeBase> Descendants(this IContentTypeBase contentType)
|
||||
{
|
||||
var contentTypeService = ApplicationContext.Current.Services.ContentTypeService;
|
||||
var descendants = contentTypeService.GetContentTypeChildren(contentType.Id)
|
||||
.FlattenList(type => contentTypeService.GetContentTypeChildren(type.Id));
|
||||
return descendants;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all descendant and self content types
|
||||
/// </summary>
|
||||
/// <param name="contentType"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<IContentTypeBase> DescendantsAndSelf(this IContentTypeBase contentType)
|
||||
{
|
||||
var descendantsAndSelf = new[] { contentType }.Concat(contentType.Descendants());
|
||||
return descendantsAndSelf;
|
||||
}
|
||||
|
||||
///// <summary>
|
||||
///// Returns the descendant content type Ids for the given content type
|
||||
///// </summary>
|
||||
///// <param name="contentType"></param>
|
||||
///// <returns></returns>
|
||||
//public static IEnumerable<int> DescendantIds(this IContentTypeBase contentType)
|
||||
//{
|
||||
// return ((ContentTypeService) ApplicationContext.Current.Services.ContentTypeService)
|
||||
// .GetDescendantContentTypeIds(contentType.Id);
|
||||
//}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -53,11 +52,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _parentId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_parentId = value;
|
||||
return _parentId;
|
||||
}, _parentId, ParentIdSelector);
|
||||
_parentId = value;
|
||||
OnPropertyChanged(ParentIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,11 +66,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
_name = value;
|
||||
OnPropertyChanged(NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,11 +80,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
_sortOrder = value;
|
||||
OnPropertyChanged(SortOrderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,11 +94,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _level; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_level = value;
|
||||
return _level;
|
||||
}, _level, LevelSelector);
|
||||
_level = value;
|
||||
OnPropertyChanged(LevelSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,11 +108,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _path; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_path = value;
|
||||
return _path;
|
||||
}, _path, PathSelector);
|
||||
_path = value;
|
||||
OnPropertyChanged(PathSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,11 +122,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, UserIdSelector);
|
||||
_creatorId = value;
|
||||
OnPropertyChanged(UserIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,11 +136,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _trashed; }
|
||||
internal set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_trashed = value;
|
||||
return _trashed;
|
||||
}, _trashed, TrashedSelector);
|
||||
_trashed = value;
|
||||
OnPropertyChanged(TrashedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,12 +149,9 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get { return _controlId; }
|
||||
private set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_controlId = value;
|
||||
return _controlId;
|
||||
}, _controlId, ControlIdSelector);
|
||||
{
|
||||
_controlId = value;
|
||||
OnPropertyChanged(ControlIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,12 +163,9 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get { return _databaseType; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_databaseType = value;
|
||||
return _databaseType;
|
||||
}, _databaseType, DatabaseTypeSelector);
|
||||
{
|
||||
_databaseType = value;
|
||||
OnPropertyChanged(DatabaseTypeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -42,11 +41,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _parentId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_parentId = value;
|
||||
return _parentId;
|
||||
}, _parentId, ParentIdSelector);
|
||||
_parentId = value;
|
||||
OnPropertyChanged(ParentIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,11 +55,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _itemKey; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_itemKey = value;
|
||||
return _itemKey;
|
||||
}, _itemKey, ItemKeySelector);
|
||||
_itemKey = value;
|
||||
OnPropertyChanged(ItemKeySelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,11 +69,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _translations; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_translations = value;
|
||||
return _translations;
|
||||
}, _translations, TranslationsSelector);
|
||||
_translations = value;
|
||||
OnPropertyChanged(TranslationsSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -41,11 +40,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _language; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_language = value;
|
||||
return _language;
|
||||
}, _language, LanguageSelector);
|
||||
_language = value;
|
||||
OnPropertyChanged(LanguageSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,11 +54,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _value; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_value = value;
|
||||
return _value;
|
||||
}, _value, ValueSelector);
|
||||
_value = value;
|
||||
OnPropertyChanged(ValueSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
@@ -10,24 +12,12 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
[DebuggerDisplay("Id: {Id}")]
|
||||
public abstract class Entity : TracksChangesEntityBase, IEntity, IRememberBeingDirty, ICanBeDirty
|
||||
public abstract class Entity : IEntity, ICanBeDirty
|
||||
{
|
||||
private bool _hasIdentity;
|
||||
private int? _hash;
|
||||
private int _id;
|
||||
private Guid _key;
|
||||
private DateTime _createDate;
|
||||
private DateTime _updateDate;
|
||||
private bool _wasCancelled;
|
||||
|
||||
private static readonly PropertyInfo IdSelector = ExpressionHelper.GetPropertyInfo<Entity, int>(x => x.Id);
|
||||
private static readonly PropertyInfo KeySelector = ExpressionHelper.GetPropertyInfo<Entity, Guid>(x => x.Key);
|
||||
private static readonly PropertyInfo CreateDateSelector = ExpressionHelper.GetPropertyInfo<Entity, DateTime>(x => x.CreateDate);
|
||||
private static readonly PropertyInfo UpdateDateSelector = ExpressionHelper.GetPropertyInfo<Entity, DateTime>(x => x.UpdateDate);
|
||||
private static readonly PropertyInfo HasIdentitySelector = ExpressionHelper.GetPropertyInfo<Entity, bool>(x => x.HasIdentity);
|
||||
private static readonly PropertyInfo WasCancelledSelector = ExpressionHelper.GetPropertyInfo<Entity, bool>(x => x.WasCancelled);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Integer Id
|
||||
@@ -41,12 +31,8 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
}
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_id = value;
|
||||
HasIdentity = true; //set the has Identity
|
||||
return _id;
|
||||
}, _id, IdSelector);
|
||||
_id = value;
|
||||
HasIdentity = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,67 +51,46 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
|
||||
return _key;
|
||||
}
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_key = value;
|
||||
return _key;
|
||||
}, _key, KeySelector);
|
||||
}
|
||||
set { _key = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Created Date
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime CreateDate
|
||||
{
|
||||
get { return _createDate; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_createDate = value;
|
||||
return _createDate;
|
||||
}, _createDate, CreateDateSelector);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// /// Gets or sets the WasCancelled flag, which is used to track
|
||||
/// whether some action against an entity was cancelled through some event.
|
||||
/// This only exists so we have a way to check if an event was cancelled through
|
||||
/// the new api, which also needs to take effect in the legacy api.
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
internal bool WasCancelled
|
||||
{
|
||||
get { return _wasCancelled; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_wasCancelled = value;
|
||||
return _wasCancelled;
|
||||
}, _wasCancelled, WasCancelledSelector);
|
||||
}
|
||||
}
|
||||
public DateTime CreateDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Modified Date
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public DateTime UpdateDate
|
||||
public DateTime UpdateDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the WasCancelled flag, which is used to track
|
||||
/// whether some action against an entity was cancelled through some event.
|
||||
/// This only exists so we have a way to check if an event was cancelled through
|
||||
/// the new api, which also needs to take effect in the legacy api.
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
internal bool WasCancelled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Property changed event
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on a property setter.
|
||||
/// </summary>
|
||||
/// <param name="propertyInfo">The property info.</param>
|
||||
protected virtual void OnPropertyChanged(PropertyInfo propertyInfo)
|
||||
{
|
||||
get { return _updateDate; }
|
||||
set
|
||||
_propertyChangedInfo[propertyInfo.Name] = true;
|
||||
|
||||
if (PropertyChanged != null)
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_updateDate = value;
|
||||
return _updateDate;
|
||||
}, _updateDate, UpdateDateSelector);
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +117,42 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
UpdateDate = DateTime.Now;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the properties that have changed
|
||||
/// </summary>
|
||||
private readonly IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a specific property on the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property to check</param>
|
||||
/// <returns>True if Property is dirty, otherwise False</returns>
|
||||
public virtual bool IsPropertyDirty(string propertyName)
|
||||
{
|
||||
return _propertyChangedInfo.Any(x => x.Key == propertyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <returns>True if entity is dirty, otherwise False</returns>
|
||||
public virtual bool IsDirty()
|
||||
{
|
||||
return _propertyChangedInfo.Any();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets dirty properties by clearing the dictionary used to track changes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note that resetting the dirty properties could potentially
|
||||
/// obstruct the saving of a new or updated entity.
|
||||
/// </remarks>
|
||||
public virtual void ResetDirtyProperties()
|
||||
{
|
||||
_propertyChangedInfo.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity has an identity, eg. Id.
|
||||
/// </summary>
|
||||
@@ -163,27 +164,10 @@ namespace Umbraco.Core.Models.EntityBase
|
||||
}
|
||||
protected set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_hasIdentity = value;
|
||||
return _hasIdentity;
|
||||
}, _hasIdentity, HasIdentitySelector);
|
||||
_hasIdentity = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(Entity left, Entity right)
|
||||
{
|
||||
if (ReferenceEquals(null, left))
|
||||
return false;
|
||||
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(Entity left, Entity right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
public virtual bool SameIdentityAs(IEntity other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
namespace Umbraco.Core.Models.EntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface that defines if the object is tracking property changes and that is is also
|
||||
/// remembering what property changes had been made after the changes were committed.
|
||||
/// </summary>
|
||||
public interface IRememberBeingDirty : ICanBeDirty
|
||||
{
|
||||
bool WasDirty();
|
||||
bool WasPropertyDirty(string propertyName);
|
||||
void ForgetPreviouslyDirtyProperties();
|
||||
}
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Umbraco.Core.Models.EntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// A base class for use to implement IRememberBeingDirty/ICanBeDirty
|
||||
/// </summary>
|
||||
public abstract class TracksChangesEntityBase : IRememberBeingDirty
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracks the properties that have changed
|
||||
/// </summary>
|
||||
private readonly IDictionary<string, bool> _propertyChangedInfo = new Dictionary<string, bool>();
|
||||
|
||||
/// <summary>
|
||||
/// Tracks the properties that we're changed before the last commit (or last call to ResetDirtyProperties)
|
||||
/// </summary>
|
||||
private IDictionary<string, bool> _lastPropertyChangedInfo = null;
|
||||
|
||||
/// <summary>
|
||||
/// Property changed event
|
||||
/// </summary>
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Method to call on a property setter.
|
||||
/// </summary>
|
||||
/// <param name="propertyInfo">The property info.</param>
|
||||
protected virtual void OnPropertyChanged(PropertyInfo propertyInfo)
|
||||
{
|
||||
_propertyChangedInfo[propertyInfo.Name] = true;
|
||||
|
||||
if (PropertyChanged != null)
|
||||
{
|
||||
PropertyChanged(this, new PropertyChangedEventArgs(propertyInfo.Name));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a specific property on the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property to check</param>
|
||||
/// <returns>True if Property is dirty, otherwise False</returns>
|
||||
public virtual bool IsPropertyDirty(string propertyName)
|
||||
{
|
||||
return _propertyChangedInfo.Any(x => x.Key == propertyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the current entity is dirty.
|
||||
/// </summary>
|
||||
/// <returns>True if entity is dirty, otherwise False</returns>
|
||||
public virtual bool IsDirty()
|
||||
{
|
||||
return _propertyChangedInfo.Any();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the entity had been changed and the changes were committed
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool WasDirty()
|
||||
{
|
||||
return _lastPropertyChangedInfo != null && _lastPropertyChangedInfo.Any();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a specific property on the current entity was changed and the changes were committed
|
||||
/// </summary>
|
||||
/// <param name="propertyName">Name of the property to check</param>
|
||||
/// <returns>True if Property was changed, otherwise False. Returns false if the entity had not been previously changed.</returns>
|
||||
public virtual bool WasPropertyDirty(string propertyName)
|
||||
{
|
||||
return WasDirty() && _lastPropertyChangedInfo.Any(x => x.Key == propertyName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the remembered dirty properties from before the last commit
|
||||
/// </summary>
|
||||
public void ForgetPreviouslyDirtyProperties()
|
||||
{
|
||||
_lastPropertyChangedInfo.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets dirty properties by clearing the dictionary used to track changes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note that resetting the dirty properties could potentially
|
||||
/// obstruct the saving of a new or updated entity.
|
||||
/// </remarks>
|
||||
public virtual void ResetDirtyProperties()
|
||||
{
|
||||
ResetDirtyProperties(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets dirty properties by clearing the dictionary used to track changes.
|
||||
/// </summary>
|
||||
/// <param name="rememberPreviouslyChangedProperties">
|
||||
/// true if we are to remember the last changes made after resetting
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// Please note that resetting the dirty properties could potentially
|
||||
/// obstruct the saving of a new or updated entity.
|
||||
/// </remarks>
|
||||
internal void ResetDirtyProperties(bool rememberPreviouslyChangedProperties)
|
||||
{
|
||||
if (rememberPreviouslyChangedProperties)
|
||||
{
|
||||
//copy the changed properties to the last changed properties
|
||||
_lastPropertyChangedInfo = _propertyChangedInfo.ToDictionary(v => v.Key, v => v.Value);
|
||||
}
|
||||
|
||||
_propertyChangedInfo.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used by inheritors to set the value of properties, this will detect if the property value actually changed and if it did
|
||||
/// it will ensure that the property has a dirty flag set.
|
||||
/// </summary>
|
||||
/// <param name="setValue"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="propertySelector"></param>
|
||||
/// <returns>returns true if the value changed</returns>
|
||||
/// <remarks>
|
||||
/// This is required because we don't want a property to show up as "dirty" if the value is the same. For example, when we
|
||||
/// save a document type, nearly all properties are flagged as dirty just because we've 'reset' them, but they are all set
|
||||
/// to the same value, so it's really not dirty.
|
||||
/// </remarks>
|
||||
internal bool SetPropertyValueAndDetectChanges<T>(Func<T, T> setValue, T value, PropertyInfo propertySelector)
|
||||
{
|
||||
var initVal = value;
|
||||
var newVal = setValue(value);
|
||||
if (!Equals(initVal, newVal))
|
||||
{
|
||||
OnPropertyChanged(propertySelector);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
@@ -13,17 +12,11 @@ namespace Umbraco.Core.Models
|
||||
[DataContract(IsReference = true)]
|
||||
public abstract class File : Entity, IFile
|
||||
{
|
||||
private string _path;
|
||||
private string _content = string.Empty; //initialize to empty string, not null
|
||||
|
||||
protected File(string path)
|
||||
{
|
||||
_path = path;
|
||||
Path = path;
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo ContentSelector = ExpressionHelper.GetPropertyInfo<File, string>(x => x.Content);
|
||||
private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo<File, string>(x => x.Path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Name of the File including extension
|
||||
/// </summary>
|
||||
@@ -55,35 +48,13 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or sets the Path to the File from the root of the site
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public virtual string Path
|
||||
{
|
||||
get { return _path; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_path = value;
|
||||
return _path;
|
||||
}, _path, PathSelector);
|
||||
}
|
||||
}
|
||||
public virtual string Path { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Content of a File
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public virtual string Content
|
||||
{
|
||||
get { return _content; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_content = value;
|
||||
return _content;
|
||||
}, _content, ContentSelector);
|
||||
}
|
||||
}
|
||||
public virtual string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Boolean indicating whether the file could be validated
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a Content object
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public interface IContent : IContentBase
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public interface IMedia : IContentBase
|
||||
{
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a ContentType, which Media is based on
|
||||
/// </summary
|
||||
/// </summary>
|
||||
public interface IMediaType : IContentTypeComposition
|
||||
{
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -34,11 +33,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _isoCode; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_isoCode = value;
|
||||
return _isoCode;
|
||||
}, _isoCode, IsoCodeSelector);
|
||||
_isoCode = value;
|
||||
OnPropertyChanged(IsoCodeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,11 +47,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _cultureName; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_cultureName = value;
|
||||
return _cultureName;
|
||||
}, _cultureName, CultureNameSelector);
|
||||
_cultureName = value;
|
||||
OnPropertyChanged(CultureNameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
@@ -13,240 +12,81 @@ namespace Umbraco.Core.Models
|
||||
[DataContract(IsReference = true)]
|
||||
internal class Macro : Entity, IMacro
|
||||
{
|
||||
private string _alias;
|
||||
private string _name;
|
||||
private bool _useInEditor;
|
||||
private int _cacheDuration;
|
||||
private bool _cacheByPage;
|
||||
private bool _cacheByMember;
|
||||
private bool _dontRender;
|
||||
private string _scriptFile;
|
||||
private string _scriptAssembly;
|
||||
private string _python;
|
||||
private string _xslt;
|
||||
private List<IMacroProperty> _properties;
|
||||
|
||||
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Alias);
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Name);
|
||||
private static readonly PropertyInfo UseInEditorSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.UseInEditor);
|
||||
private static readonly PropertyInfo CacheDurationSelector = ExpressionHelper.GetPropertyInfo<Macro, int>(x => x.CacheDuration);
|
||||
private static readonly PropertyInfo CacheByPageSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.CacheByPage);
|
||||
private static readonly PropertyInfo CacheByMemberSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.CacheByMember);
|
||||
private static readonly PropertyInfo DontRenderSelector = ExpressionHelper.GetPropertyInfo<Macro, bool>(x => x.DontRender);
|
||||
private static readonly PropertyInfo ScriptFileSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ScriptFile);
|
||||
private static readonly PropertyInfo ScriptAssemblySelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.ScriptAssembly);
|
||||
private static readonly PropertyInfo PythonSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Python);
|
||||
private static readonly PropertyInfo XsltSelector = ExpressionHelper.GetPropertyInfo<Macro, string>(x => x.Xslt);
|
||||
private static readonly PropertyInfo PropertiesSelector = ExpressionHelper.GetPropertyInfo<Macro, List<IMacroProperty>>(x => x.Properties);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the alias of the Macro
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Alias
|
||||
{
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_alias = value;
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
}
|
||||
}
|
||||
public string Alias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the Macro
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro can be used in an Editor
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool UseInEditor
|
||||
{
|
||||
get { return _useInEditor; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_useInEditor = value;
|
||||
return _useInEditor;
|
||||
}, _useInEditor, UseInEditorSelector);
|
||||
}
|
||||
}
|
||||
public bool UseInEditor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Cache Duration for the Macro
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int CacheDuration
|
||||
{
|
||||
get { return _cacheDuration; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_cacheDuration = value;
|
||||
return _cacheDuration;
|
||||
}, _cacheDuration, CacheDurationSelector);
|
||||
}
|
||||
}
|
||||
public int CacheDuration { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro should be Cached by Page
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool CacheByPage
|
||||
{
|
||||
get { return _cacheByPage; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_cacheByPage = value;
|
||||
return _cacheByPage;
|
||||
}, _cacheByPage, CacheByPageSelector);
|
||||
}
|
||||
}
|
||||
public bool CacheByPage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro should be Cached Personally
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool CacheByMember
|
||||
{
|
||||
get { return _cacheByMember; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_cacheByMember = value;
|
||||
return _cacheByMember;
|
||||
}, _cacheByMember, CacheByMemberSelector);
|
||||
}
|
||||
}
|
||||
public bool CacheByMember { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean indicating whether the Macro should be rendered in an Editor
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public bool DontRender
|
||||
{
|
||||
get { return _dontRender; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_dontRender = value;
|
||||
return _dontRender;
|
||||
}, _dontRender, DontRenderSelector);
|
||||
}
|
||||
}
|
||||
public bool DontRender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to the script file in use
|
||||
/// </summary>
|
||||
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
|
||||
[DataMember]
|
||||
public string ScriptFile
|
||||
{
|
||||
get { return _scriptFile; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_scriptFile = value;
|
||||
return _scriptFile;
|
||||
}, _scriptFile, ScriptFileSelector);
|
||||
}
|
||||
}
|
||||
public string ScriptFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the assembly, which should be used by the Macro
|
||||
/// </summary>
|
||||
/// <remarks>Will usually only be filled if the ScriptFile is a Usercontrol</remarks>
|
||||
[DataMember]
|
||||
public string ScriptAssembly
|
||||
{
|
||||
get { return _scriptAssembly; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_scriptAssembly = value;
|
||||
return _scriptAssembly;
|
||||
}, _scriptAssembly, ScriptAssemblySelector);
|
||||
}
|
||||
}
|
||||
public string ScriptAssembly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or set the path to the Python file in use
|
||||
/// </summary>
|
||||
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
|
||||
[DataMember]
|
||||
public string Python
|
||||
{
|
||||
get { return _python; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_python = value;
|
||||
return _python;
|
||||
}, _python, PythonSelector);
|
||||
}
|
||||
}
|
||||
public string Python { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to the Xslt file in use
|
||||
/// </summary>
|
||||
/// <remarks>Optional: Can only be one of three Script, Python or Xslt</remarks>
|
||||
[DataMember]
|
||||
public string Xslt
|
||||
{
|
||||
get { return _xslt; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_xslt = value;
|
||||
return _xslt;
|
||||
}, _xslt, XsltSelector);
|
||||
}
|
||||
}
|
||||
public string Xslt { get; set; }
|
||||
|
||||
//TODO: This needs to be changed to a custom collection class so we can track the dirtyness of each property!
|
||||
/// <summary>
|
||||
/// Gets or sets a list of Macro Properties
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public List<IMacroProperty> Properties
|
||||
{
|
||||
get { return _properties; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_properties = value;
|
||||
return _properties;
|
||||
}, _properties, PropertiesSelector);
|
||||
}
|
||||
}
|
||||
public List<IMacroProperty> Properties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Overridden this method in order to set a random Id
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -10,68 +8,25 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class MacroProperty : TracksChangesEntityBase, IMacroProperty, IRememberBeingDirty
|
||||
internal class MacroProperty : IMacroProperty
|
||||
{
|
||||
private string _alias;
|
||||
private string _name;
|
||||
private int _sortOrder;
|
||||
private IMacroPropertyType _propertyType;
|
||||
|
||||
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, string>(x => x.Alias);
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, string>(x => x.Name);
|
||||
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, int>(x => x.SortOrder);
|
||||
private static readonly PropertyInfo PropertyTypeSelector = ExpressionHelper.GetPropertyInfo<MacroProperty, IMacroPropertyType>(x => x.PropertyType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Alias of the Property
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Alias
|
||||
{
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_alias = value;
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
}
|
||||
}
|
||||
public string Alias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Name of the Property
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Sort Order of the Property
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public int SortOrder
|
||||
{
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
}
|
||||
}
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Type for this Property
|
||||
@@ -81,18 +36,6 @@ namespace Umbraco.Core.Models
|
||||
/// All types was previously contained in the database, but has been ported to code.
|
||||
/// </remarks>
|
||||
[DataMember]
|
||||
public IMacroPropertyType PropertyType
|
||||
|
||||
{
|
||||
get { return _propertyType; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_propertyType = value;
|
||||
return _propertyType;
|
||||
}, _propertyType, PropertyTypeSelector);
|
||||
}
|
||||
}
|
||||
public IMacroPropertyType PropertyType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
|
||||
internal interface IUserType : IAggregateRoot
|
||||
{
|
||||
string Alias { get; set; }
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -83,11 +82,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _version; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_version = value;
|
||||
return _version;
|
||||
}, _version, VersionSelector);
|
||||
_version = value;
|
||||
OnPropertyChanged(VersionSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,11 +108,8 @@ namespace Umbraco.Core.Models
|
||||
"Type validation failed. The value type: '{0}' does not match the DataType in PropertyType with alias: '{1}'",
|
||||
value == null ? "null" : value.GetType().Name, Alias));
|
||||
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_value = value;
|
||||
return _value;
|
||||
}, _value, ValueSelector);
|
||||
_value = value;
|
||||
OnPropertyChanged(ValueSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Specialized;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -46,11 +45,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
_name = value;
|
||||
OnPropertyChanged(NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,11 +82,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
_sortOrder = value;
|
||||
OnPropertyChanged(SortOrderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -14,7 +13,6 @@ namespace Umbraco.Core.Models
|
||||
[DataContract(IsReference = true)]
|
||||
public class PropertyType : Entity, IEquatable<PropertyType>
|
||||
{
|
||||
//private SerializationService _service;
|
||||
private string _name;
|
||||
private string _alias;
|
||||
private string _description;
|
||||
@@ -34,22 +32,12 @@ namespace Umbraco.Core.Models
|
||||
|
||||
DataTypeId = dataTypeDefinition.ControlId;
|
||||
DataTypeDatabaseType = dataTypeDefinition.DatabaseType;
|
||||
|
||||
EnsureSerializationService();
|
||||
}
|
||||
|
||||
internal PropertyType(Guid dataTypeControlId, DataTypeDatabaseType dataTypeDatabaseType)
|
||||
{
|
||||
DataTypeId = dataTypeControlId;
|
||||
DataTypeDatabaseType = dataTypeDatabaseType;
|
||||
|
||||
EnsureSerializationService();
|
||||
}
|
||||
|
||||
private void EnsureSerializationService()
|
||||
{
|
||||
/*var serviceStackSerializer = new ServiceStackXmlSerializer();
|
||||
_service = new SerializationService(serviceStackSerializer);*/
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Name);
|
||||
@@ -73,11 +61,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
_name = value;
|
||||
OnPropertyChanged(NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,11 +75,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_alias = value;
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
_alias = value;
|
||||
OnPropertyChanged(AliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,11 +89,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _description; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_description = value;
|
||||
return _description;
|
||||
}, _description, DescriptionSelector);
|
||||
_description = value;
|
||||
OnPropertyChanged(DescriptionSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,11 +104,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _dataTypeDefinitionId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_dataTypeDefinitionId = value;
|
||||
return _dataTypeDefinitionId;
|
||||
}, _dataTypeDefinitionId, DataTypeDefinitionIdSelector);
|
||||
_dataTypeDefinitionId = value;
|
||||
OnPropertyChanged(DataTypeDefinitionIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,11 +119,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _dataTypeId; }
|
||||
internal set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_dataTypeId = value;
|
||||
return _dataTypeId;
|
||||
}, _dataTypeId, DataTypeControlIdSelector);
|
||||
_dataTypeId = value;
|
||||
OnPropertyChanged(DataTypeControlIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,11 +133,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _dataTypeDatabaseType; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_dataTypeDatabaseType = value;
|
||||
return _dataTypeDatabaseType;
|
||||
}, _dataTypeDatabaseType, DataTypeDatabaseTypeSelector);
|
||||
_dataTypeDatabaseType = value;
|
||||
OnPropertyChanged(DataTypeDatabaseTypeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,11 +147,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _propertyGroupId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_propertyGroupId = value;
|
||||
return _propertyGroupId;
|
||||
}, _propertyGroupId, PropertyGroupIdSelector);
|
||||
_propertyGroupId = value;
|
||||
OnPropertyChanged(PropertyGroupIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,11 +161,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _mandatory; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_mandatory = value;
|
||||
return _mandatory;
|
||||
}, _mandatory, MandatorySelector);
|
||||
_mandatory = value;
|
||||
OnPropertyChanged(MandatorySelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,16 +170,14 @@ namespace Umbraco.Core.Models
|
||||
/// Gets of Sets the Help text for the current PropertyType
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
[Obsolete("Not used anywhere in the UI")]
|
||||
public string HelpText
|
||||
{
|
||||
get { return _helpText; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_helpText = value;
|
||||
return _helpText;
|
||||
}, _helpText, HelpTextSelector);
|
||||
_helpText = value;
|
||||
OnPropertyChanged(HelpTextSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,11 +190,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
_sortOrder = value;
|
||||
OnPropertyChanged(SortOrderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,19 +199,15 @@ namespace Umbraco.Core.Models
|
||||
/// Gets or Sets the RegEx for validation of legacy DataTypes
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
internal string ValidationRegExp
|
||||
public string ValidationRegExp
|
||||
{
|
||||
get { return _validationRegExp; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_validationRegExp = value;
|
||||
return _validationRegExp;
|
||||
}, _validationRegExp, ValidationRegExpSelector);
|
||||
_validationRegExp = value;
|
||||
OnPropertyChanged(ValidationRegExpSelector);
|
||||
}
|
||||
}
|
||||
//Note that Validation should eventually come from PropertyEditors like in v5
|
||||
|
||||
/// <summary>
|
||||
/// Create a new Property object from a "raw" database value.
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
|
||||
namespace Umbraco.Core.Models.Rdbms
|
||||
{
|
||||
[TableName("umbracoServer")]
|
||||
[PrimaryKey("id")]
|
||||
[ExplicitColumns]
|
||||
internal class ServerRegistrationDto
|
||||
{
|
||||
[Column("id")]
|
||||
[PrimaryKeyColumn(AutoIncrement = true)]
|
||||
public int Id { get; set; }
|
||||
|
||||
[Column("address")]
|
||||
[Length(500)]
|
||||
public string Address { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A unique column in the database, a computer name must always be unique!
|
||||
/// </summary>
|
||||
[Column("computerName")]
|
||||
[Length(255)]
|
||||
[Index(IndexTypes.UniqueNonClustered, Name = "IX_computerName")]
|
||||
public string ComputerName { get; set; }
|
||||
|
||||
[Column("registeredDate")]
|
||||
[Constraint(Default = "getdate()")]
|
||||
public DateTime DateRegistered { get; set; }
|
||||
|
||||
[Column("lastNotifiedDate")]
|
||||
[Constraint(Default = "getdate()")]
|
||||
public DateTime LastNotified { get; set; }
|
||||
|
||||
[Column("isActive")]
|
||||
[Index(IndexTypes.NonClustered)]
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -40,11 +39,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _parentId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_parentId = value;
|
||||
return _parentId;
|
||||
}, _parentId, ParentIdSelector);
|
||||
_parentId = value;
|
||||
OnPropertyChanged(ParentIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,11 +53,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _childId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_childId = value;
|
||||
return _childId;
|
||||
}, _childId, ChildIdSelector);
|
||||
_childId = value;
|
||||
OnPropertyChanged(ChildIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,11 +67,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _relationType; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_relationType = value;
|
||||
return _relationType;
|
||||
}, _relationType, RelationTypeSelector);
|
||||
_relationType = value;
|
||||
OnPropertyChanged(RelationTypeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,11 +81,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _comment; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_comment = value;
|
||||
return _comment;
|
||||
}, _comment, CommentSelector);
|
||||
_comment = value;
|
||||
OnPropertyChanged(CommentSelector);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -41,11 +40,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
_name = value;
|
||||
OnPropertyChanged(NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,11 +54,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_alias = value;
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
_alias = value;
|
||||
OnPropertyChanged(AliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,11 +68,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _isBidrectional; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_isBidrectional = value;
|
||||
return _isBidrectional;
|
||||
}, _isBidrectional, IsBidirectionalSelector);
|
||||
_isBidrectional = value;
|
||||
OnPropertyChanged(IsBidirectionalSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,11 +83,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _parentObjectType; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_parentObjectType = value;
|
||||
return _parentObjectType;
|
||||
}, _parentObjectType, ParentObjectTypeSelector);
|
||||
_parentObjectType = value;
|
||||
OnPropertyChanged(ParentObjectTypeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,11 +98,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _childObjectType; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_childObjectType = value;
|
||||
return _childObjectType;
|
||||
}, _childObjectType, ChildObjectTypeSelector);
|
||||
_childObjectType = value;
|
||||
OnPropertyChanged(ChildObjectTypeSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@ namespace Umbraco.Core.Models
|
||||
dirs += "," + SystemDirectories.MvcViews;*/
|
||||
|
||||
//Validate file
|
||||
var validFile = IOHelper.VerifyEditPath(Path, dirs.Split(','));
|
||||
var validFile = IOHelper.ValidateEditPath(Path, dirs.Split(','));
|
||||
|
||||
//Validate extension
|
||||
var validExtension = IOHelper.VerifyFileExtension(Path, exts);
|
||||
var validExtension = IOHelper.ValidateFileExtension(Path, exts);
|
||||
|
||||
return validFile && validExtension;
|
||||
}
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
using Umbraco.Core.Sync;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
internal class ServerRegistration : Entity, IServerAddress, IAggregateRoot
|
||||
{
|
||||
private string _serverAddress;
|
||||
private string _computerName;
|
||||
private bool _isActive;
|
||||
|
||||
private static readonly PropertyInfo ServerAddressSelector = ExpressionHelper.GetPropertyInfo<ServerRegistration, string>(x => x.ServerAddress);
|
||||
private static readonly PropertyInfo ComputerNameSelector = ExpressionHelper.GetPropertyInfo<ServerRegistration, string>(x => x.ComputerName);
|
||||
private static readonly PropertyInfo IsActiveSelector = ExpressionHelper.GetPropertyInfo<ServerRegistration, bool>(x => x.IsActive);
|
||||
|
||||
public ServerRegistration()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an item with pre-filled properties
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="serverAddress"></param>
|
||||
/// <param name="computerName"></param>
|
||||
/// <param name="createDate"></param>
|
||||
/// <param name="updateDate"></param>
|
||||
/// <param name="isActive"></param>
|
||||
public ServerRegistration(int id, string serverAddress, string computerName, DateTime createDate, DateTime updateDate, bool isActive)
|
||||
{
|
||||
UpdateDate = updateDate;
|
||||
CreateDate = createDate;
|
||||
Key = Id.ToString().EncodeAsGuid();
|
||||
Id = id;
|
||||
ServerAddress = serverAddress;
|
||||
ComputerName = computerName;
|
||||
IsActive = isActive;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance for persisting a new item
|
||||
/// </summary>
|
||||
/// <param name="serverAddress"></param>
|
||||
/// <param name="computerName"></param>
|
||||
/// <param name="createDate"></param>
|
||||
public ServerRegistration(string serverAddress, string computerName, DateTime createDate)
|
||||
{
|
||||
CreateDate = createDate;
|
||||
UpdateDate = createDate;
|
||||
Key = 0.ToString().EncodeAsGuid();
|
||||
ServerAddress = serverAddress;
|
||||
ComputerName = computerName;
|
||||
}
|
||||
|
||||
public string ServerAddress
|
||||
{
|
||||
get { return _serverAddress; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_serverAddress = value;
|
||||
return _serverAddress;
|
||||
}, _serverAddress, ServerAddressSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public string ComputerName
|
||||
{
|
||||
get { return _computerName; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_computerName = value;
|
||||
return _computerName;
|
||||
}, _computerName, ComputerNameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsActive
|
||||
{
|
||||
get { return _isActive; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_isActive = value;
|
||||
return _isActive;
|
||||
}, _isActive, IsActiveSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models.Css;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -118,10 +119,10 @@ namespace Umbraco.Core.Models
|
||||
var dirs = SystemDirectories.Css;
|
||||
|
||||
//Validate file
|
||||
var validFile = IOHelper.VerifyEditPath(Path, dirs.Split(','));
|
||||
var validFile = IOHelper.ValidateEditPath(Path, dirs.Split(','));
|
||||
|
||||
//Validate extension
|
||||
var validExtension = IOHelper.VerifyFileExtension(Path, new List<string> {"css"});
|
||||
var validExtension = IOHelper.ValidateFileExtension(Path, new List<string> {"css"});
|
||||
|
||||
return validFile && validExtension;
|
||||
}
|
||||
@@ -158,4 +159,25 @@ namespace Umbraco.Core.Models
|
||||
get { return string.IsNullOrEmpty(Path) == false; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a Stylesheet Property
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Properties are always formatted to have a single selector, so it can be used in the backoffice
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
public class StylesheetProperty : IValueObject
|
||||
{
|
||||
public StylesheetProperty(string @alias, string value)
|
||||
{
|
||||
Alias = alias;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Alias { get; set; }
|
||||
public string Value { get; set; }
|
||||
public bool IsPartOfAtRule { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Stylesheet Property
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Properties are always formatted to have a single selector, so it can be used in the backoffice
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
public class StylesheetProperty : IValueObject
|
||||
{
|
||||
public StylesheetProperty(string @alias, string value)
|
||||
{
|
||||
Alias = alias;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
public string Alias { get; set; }
|
||||
public string Value { get; set; }
|
||||
public bool IsPartOfAtRule { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -40,11 +40,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _closed; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_closed = value;
|
||||
return _closed;
|
||||
}, _closed, ClosedSelector);
|
||||
_closed = value;
|
||||
OnPropertyChanged(ClosedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,11 +54,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _taskType; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_taskType = value;
|
||||
return _taskType;
|
||||
}, _taskType, TaskTypeSelector);
|
||||
_taskType = value;
|
||||
OnPropertyChanged(TaskTypeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,11 +68,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _entityId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_entityId = value;
|
||||
return _entityId;
|
||||
}, _entityId, EntityIdSelector);
|
||||
_entityId = value;
|
||||
OnPropertyChanged(EntityIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,11 +82,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _ownerUserId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_ownerUserId = value;
|
||||
return _ownerUserId;
|
||||
}, _ownerUserId, OwnerUserIdSelector);
|
||||
_ownerUserId = value;
|
||||
OnPropertyChanged(OwnerUserIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,11 +96,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _assigneeUserId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_assigneeUserId = value;
|
||||
return _assigneeUserId;
|
||||
}, _assigneeUserId, AssigneeUserIdSelector);
|
||||
_assigneeUserId = value;
|
||||
OnPropertyChanged(AssigneeUserIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,11 +110,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _comment; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_comment = value;
|
||||
return _comment;
|
||||
}, _comment, CommentSelector);
|
||||
_comment = value;
|
||||
OnPropertyChanged(CommentSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,8 @@ namespace Umbraco.Core.Models
|
||||
get { return _alias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_alias = value;
|
||||
return _alias;
|
||||
}, _alias, AliasSelector);
|
||||
_alias = value;
|
||||
OnPropertyChanged(AliasSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.IO;
|
||||
@@ -16,22 +15,6 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
private readonly string _alias;
|
||||
private readonly string _name;
|
||||
private int _creatorId;
|
||||
private int _level;
|
||||
private int _sortOrder;
|
||||
private int _parentId;
|
||||
private string _nodePath;
|
||||
private int _masterTemplateId;
|
||||
private string _masterTemplateAlias;
|
||||
|
||||
private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo<Template, int>(x => x.CreatorId);
|
||||
private static readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo<Template, int>(x => x.Level);
|
||||
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<Template, int>(x => x.SortOrder);
|
||||
private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo<Template, int>(x => x.ParentId);
|
||||
private static readonly PropertyInfo NodePathSelector = ExpressionHelper.GetPropertyInfo<Template, string>(x => x.NodePath);
|
||||
//private static readonly PropertyInfo MasterTemplateIdSelector = ExpressionHelper.GetPropertyInfo<Template, int>(x => x.MasterTemplateId);
|
||||
private static readonly PropertyInfo MasterTemplateAliasSelector = ExpressionHelper.GetPropertyInfo<Template, string>(x => x.MasterTemplateAlias);
|
||||
|
||||
|
||||
internal Template(string path)
|
||||
: base(path)
|
||||
@@ -45,100 +28,30 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
base.Path = path;
|
||||
ParentId = -1;
|
||||
Key = name.EncodeAsGuid();
|
||||
_name = name.Replace("/", ".").Replace("\\", "");
|
||||
_alias = alias.ToSafeAlias();
|
||||
|
||||
CreateDate = DateTime.Now;
|
||||
UpdateDate = DateTime.Now;
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
internal int CreatorId
|
||||
{
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, CreatorIdSelector);
|
||||
}
|
||||
}
|
||||
internal int CreatorId { get; set; }
|
||||
|
||||
[DataMember]
|
||||
internal int Level
|
||||
{
|
||||
get { return _level; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_level = value;
|
||||
return _level;
|
||||
}, _level, LevelSelector);
|
||||
}
|
||||
}
|
||||
internal int Level { get; set; }
|
||||
|
||||
[DataMember]
|
||||
internal int SortOrder
|
||||
{
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
}
|
||||
}
|
||||
internal int SortOrder { get; set; }
|
||||
|
||||
[DataMember]
|
||||
internal int ParentId
|
||||
{
|
||||
get { return _parentId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_parentId = value;
|
||||
return _parentId;
|
||||
}, _parentId, ParentIdSelector);
|
||||
}
|
||||
}
|
||||
internal int ParentId { get; set; }
|
||||
|
||||
[DataMember]
|
||||
internal string NodePath
|
||||
{
|
||||
get { return _nodePath; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_nodePath = value;
|
||||
return _nodePath;
|
||||
}, _nodePath, NodePathSelector);
|
||||
}
|
||||
}
|
||||
internal string NodePath { get; set; }
|
||||
|
||||
[DataMember]
|
||||
internal Lazy<int> MasterTemplateId { get; set; }
|
||||
|
||||
[DataMember]
|
||||
internal string MasterTemplateAlias
|
||||
{
|
||||
get { return _masterTemplateAlias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_masterTemplateAlias = value;
|
||||
return _masterTemplateAlias;
|
||||
}, _masterTemplateAlias, MasterTemplateAliasSelector);
|
||||
}
|
||||
}
|
||||
internal string MasterTemplateAlias { get; set; }
|
||||
|
||||
[DataMember]
|
||||
public override string Alias
|
||||
@@ -184,7 +97,7 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
else
|
||||
{
|
||||
exts.Add(UmbracoSettings.UseAspNetMasterPages ? "master" : "aspx");
|
||||
exts.Add(UmbracoSettings.UseAspNetMasterPages ? "masterpage" : "aspx");
|
||||
}
|
||||
|
||||
var dirs = SystemDirectories.Masterpages;
|
||||
@@ -192,12 +105,24 @@ namespace Umbraco.Core.Models
|
||||
dirs += "," + SystemDirectories.MvcViews;
|
||||
|
||||
//Validate file
|
||||
var validFile = IOHelper.VerifyEditPath(Path, dirs.Split(','));
|
||||
var validFile = IOHelper.ValidateEditPath(Path, dirs.Split(','));
|
||||
|
||||
//Validate extension
|
||||
var validExtension = IOHelper.VerifyFileExtension(Path, exts);
|
||||
var validExtension = IOHelper.ValidateFileExtension(Path, exts);
|
||||
|
||||
return validFile && validExtension;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,263 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of the <see cref="IUmbracoEntity"/> for internal use.
|
||||
/// </summary>
|
||||
internal class UmbracoEntity : Entity, IUmbracoEntity
|
||||
{
|
||||
private int _creatorId;
|
||||
private int _level;
|
||||
private string _name;
|
||||
private int _parentId;
|
||||
private string _path;
|
||||
private int _sortOrder;
|
||||
private bool _trashed;
|
||||
private bool _hasChildren;
|
||||
private bool _isPublished;
|
||||
private bool _isDraft;
|
||||
private bool _hasPendingChanges;
|
||||
private string _contentTypeAlias;
|
||||
private string _umbracoFile;
|
||||
private Guid _nodeObjectTypeId;
|
||||
|
||||
private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, int>(x => x.CreatorId);
|
||||
private static readonly PropertyInfo LevelSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, int>(x => x.Level);
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, string>(x => x.Name);
|
||||
private static readonly PropertyInfo ParentIdSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, int>(x => x.ParentId);
|
||||
private static readonly PropertyInfo PathSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, string>(x => x.Path);
|
||||
private static readonly PropertyInfo SortOrderSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, int>(x => x.SortOrder);
|
||||
private static readonly PropertyInfo TrashedSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, bool>(x => x.Trashed);
|
||||
private static readonly PropertyInfo HasChildrenSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, bool>(x => x.HasChildren);
|
||||
private static readonly PropertyInfo IsPublishedSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, bool>(x => x.IsPublished);
|
||||
private static readonly PropertyInfo IsDraftSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, bool>(x => x.IsDraft);
|
||||
private static readonly PropertyInfo HasPendingChangesSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, bool>(x => x.HasPendingChanges);
|
||||
private static readonly PropertyInfo ContentTypeAliasSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, string>(x => x.ContentTypeAlias);
|
||||
private static readonly PropertyInfo ContentTypeIconSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, string>(x => x.ContentTypeIcon);
|
||||
private static readonly PropertyInfo ContentTypeThumbnailSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, string>(x => x.ContentTypeThumbnail);
|
||||
private static readonly PropertyInfo UmbracoFileSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, string>(x => x.UmbracoFile);
|
||||
private static readonly PropertyInfo NodeObjectTypeIdSelector = ExpressionHelper.GetPropertyInfo<UmbracoEntity, Guid>(x => x.NodeObjectTypeId);
|
||||
private string _contentTypeIcon;
|
||||
private string _contentTypeThumbnail;
|
||||
|
||||
public UmbracoEntity()
|
||||
{
|
||||
}
|
||||
|
||||
public UmbracoEntity(bool trashed)
|
||||
{
|
||||
Trashed = trashed;
|
||||
}
|
||||
|
||||
public int CreatorId
|
||||
{
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, CreatorIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public int Level
|
||||
{
|
||||
get { return _level; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_level = value;
|
||||
return _level;
|
||||
}, _level, LevelSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public int ParentId
|
||||
{
|
||||
get { return _parentId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_parentId = value;
|
||||
return _parentId;
|
||||
}, _parentId, ParentIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public string Path
|
||||
{
|
||||
get { return _path; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_path = value;
|
||||
return _path;
|
||||
}, _path, PathSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public int SortOrder
|
||||
{
|
||||
get { return _sortOrder; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_sortOrder = value;
|
||||
return _sortOrder;
|
||||
}, _sortOrder, SortOrderSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public bool Trashed
|
||||
{
|
||||
get { return _trashed; }
|
||||
private set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_trashed = value;
|
||||
return _trashed;
|
||||
}, _trashed, TrashedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasChildren
|
||||
{
|
||||
get { return _hasChildren; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_hasChildren = value;
|
||||
return _hasChildren;
|
||||
}, _hasChildren, HasChildrenSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPublished
|
||||
{
|
||||
get { return _isPublished; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_isPublished = value;
|
||||
return _isPublished;
|
||||
}, _isPublished, IsPublishedSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsDraft
|
||||
{
|
||||
get { return _isPublished; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_isDraft = value;
|
||||
return _isDraft;
|
||||
}, _isDraft, IsDraftSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasPendingChanges
|
||||
{
|
||||
get { return _hasPendingChanges; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_hasPendingChanges = value;
|
||||
return _hasPendingChanges;
|
||||
}, _hasPendingChanges, HasPendingChangesSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public string ContentTypeAlias
|
||||
{
|
||||
get { return _contentTypeAlias; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_contentTypeAlias = value;
|
||||
return _contentTypeAlias;
|
||||
}, _contentTypeAlias, ContentTypeAliasSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public string ContentTypeIcon
|
||||
{
|
||||
get { return _contentTypeIcon; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_contentTypeIcon = value;
|
||||
return _contentTypeIcon;
|
||||
}, _contentTypeIcon, ContentTypeIconSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public string ContentTypeThumbnail
|
||||
{
|
||||
get { return _contentTypeThumbnail; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_contentTypeThumbnail = value;
|
||||
return _contentTypeThumbnail;
|
||||
}, _contentTypeThumbnail, ContentTypeThumbnailSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public string UmbracoFile
|
||||
{
|
||||
get { return _umbracoFile; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_umbracoFile = value;
|
||||
return _umbracoFile;
|
||||
}, _umbracoFile, UmbracoFileSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public Guid NodeObjectTypeId
|
||||
{
|
||||
get { return _nodeObjectTypeId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_nodeObjectTypeId = value;
|
||||
return _nodeObjectTypeId;
|
||||
}, _nodeObjectTypeId, NodeObjectTypeIdSelector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Enum used to represent the Umbraco Object Types and thier associated GUIDs
|
||||
/// </summary>
|
||||
public enum UmbracoObjectTypes
|
||||
{
|
||||
/// <summary>
|
||||
/// Default value
|
||||
/// </summary>
|
||||
Unknown,
|
||||
|
||||
/// <summary>
|
||||
/// Content Item Type
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.ContentItemType)]
|
||||
[FriendlyName("Content Item Type")]
|
||||
ContentItemType,
|
||||
|
||||
/// <summary>
|
||||
/// Root
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.SystemRoot)]
|
||||
[FriendlyName("Root")]
|
||||
ROOT,
|
||||
|
||||
/// <summary>
|
||||
/// Document
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.Document, typeof(IContent))]
|
||||
[FriendlyName("Document")]
|
||||
Document,
|
||||
|
||||
/// <summary>
|
||||
/// Media
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.Media, typeof(IMedia))]
|
||||
[FriendlyName("Media")]
|
||||
Media,
|
||||
|
||||
/// <summary>
|
||||
/// Member Type
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.MemberType)]
|
||||
[FriendlyName("Member Type")]
|
||||
MemberType,
|
||||
|
||||
/// <summary>
|
||||
/// Template
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.Template, typeof(ITemplate))]
|
||||
[FriendlyName("Template")]
|
||||
Template,
|
||||
|
||||
/// <summary>
|
||||
/// Member Group
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.MemberGroup)]
|
||||
[FriendlyName("Member Group")]
|
||||
MemberGroup,
|
||||
|
||||
/// <summary>
|
||||
/// Content Item
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.ContentItem)]
|
||||
[FriendlyName("Content Item")]
|
||||
ContentItem,
|
||||
|
||||
/// <summary>
|
||||
/// "Media Type
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.MediaType, typeof(IMediaType))]
|
||||
[FriendlyName("Media Type")]
|
||||
MediaType,
|
||||
|
||||
/// <summary>
|
||||
/// Document Type
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.DocumentType, typeof(IContentType))]
|
||||
[FriendlyName("Document Type")]
|
||||
DocumentType,
|
||||
|
||||
/// <summary>
|
||||
/// Recycle Bin
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.ContentRecycleBin)]
|
||||
[FriendlyName("Recycle Bin")]
|
||||
RecycleBin,
|
||||
|
||||
/// <summary>
|
||||
/// Stylesheet
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.Stylesheet)]
|
||||
[FriendlyName("Stylesheet")]
|
||||
Stylesheet,
|
||||
|
||||
/// <summary>
|
||||
/// Member
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.Member)]
|
||||
[FriendlyName("Member")]
|
||||
Member,
|
||||
|
||||
/// <summary>
|
||||
/// Data Type
|
||||
/// </summary>
|
||||
[UmbracoObjectTypeAttribute(Constants.ObjectTypes.DataType, typeof(IDataTypeDefinition))]
|
||||
[FriendlyName("Data Type")]
|
||||
DataType
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.CodeAnnotations;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for the UmbracoObjectTypes enum
|
||||
/// </summary>
|
||||
public static class UmbracoObjectTypesExtensions
|
||||
{
|
||||
private static readonly Dictionary<UmbracoObjectTypes, Guid> UmbracoObjectTypeCache = new Dictionary<UmbracoObjectTypes,Guid>();
|
||||
|
||||
/// <summary>
|
||||
/// Get an UmbracoObjectTypes value from it's name
|
||||
/// </summary>
|
||||
/// <param name="name">Enum value name</param>
|
||||
/// <returns>an UmbracoObjectTypes Enum value</returns>
|
||||
public static UmbracoObjectTypes GetUmbracoObjectType(string name)
|
||||
{
|
||||
return (UmbracoObjectTypes)Enum.Parse(typeof(UmbracoObjectTypes), name, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an instance of an UmbracoObjectTypes enum value from it's GUID
|
||||
/// </summary>
|
||||
/// <param name="guid">Enum value GUID</param>
|
||||
/// <returns>an UmbracoObjectTypes Enum value</returns>
|
||||
public static UmbracoObjectTypes GetUmbracoObjectType(Guid guid)
|
||||
{
|
||||
var umbracoObjectType = UmbracoObjectTypes.Unknown;
|
||||
|
||||
foreach (var name in Enum.GetNames(typeof(UmbracoObjectTypes)))
|
||||
{
|
||||
if (GetUmbracoObjectType(name).GetGuid() == guid)
|
||||
{
|
||||
umbracoObjectType = GetUmbracoObjectType(name);
|
||||
}
|
||||
}
|
||||
|
||||
return umbracoObjectType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension method for the UmbracoObjectTypes enum to return the enum GUID
|
||||
/// </summary>
|
||||
/// <param name="umbracoObjectType">UmbracoObjectTypes Enum value</param>
|
||||
/// <returns>a GUID value of the UmbracoObjectTypes</returns>
|
||||
public static Guid GetGuid(this UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
if (UmbracoObjectTypeCache.ContainsKey(umbracoObjectType))
|
||||
return UmbracoObjectTypeCache[umbracoObjectType];
|
||||
|
||||
var type = typeof(UmbracoObjectTypes);
|
||||
var memInfo = type.GetMember(umbracoObjectType.ToString());
|
||||
var attributes = memInfo[0].GetCustomAttributes(typeof(UmbracoObjectTypeAttribute),
|
||||
false);
|
||||
|
||||
if (attributes.Length == 0)
|
||||
return Guid.Empty;
|
||||
|
||||
var attribute = ((UmbracoObjectTypeAttribute)attributes[0]);
|
||||
if (attribute == null)
|
||||
return Guid.Empty;
|
||||
|
||||
UmbracoObjectTypeCache.Add(umbracoObjectType, attribute.ObjectId);
|
||||
|
||||
return attribute.ObjectId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension method for the UmbracoObjectTypes enum to return the enum name
|
||||
/// </summary>
|
||||
/// <param name="umbracoObjectType">UmbracoObjectTypes value</param>
|
||||
/// <returns>The enum name of the UmbracoObjectTypes value</returns>
|
||||
public static string GetName(this UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
return Enum.GetName(typeof(UmbracoObjectTypes), umbracoObjectType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension method for the UmbracoObejctTypes enum to return the enum friendly name
|
||||
/// </summary>
|
||||
/// <param name="umbracoObjectType">UmbracoObjectTypes value</param>
|
||||
/// <returns>a string of the FriendlyName</returns>
|
||||
public static string GetFriendlyName(this UmbracoObjectTypes umbracoObjectType)
|
||||
{
|
||||
var type = typeof(UmbracoObjectTypes);
|
||||
var memInfo = type.GetMember(umbracoObjectType.ToString());
|
||||
var attributes = memInfo[0].GetCustomAttributes(typeof(UmbracoObjectTypeAttribute),
|
||||
false);
|
||||
|
||||
if (attributes.Length == 0)
|
||||
return string.Empty;
|
||||
|
||||
var attribute = ((UmbracoObjectTypeAttribute)attributes[0]);
|
||||
if (attribute == null)
|
||||
return string.Empty;
|
||||
|
||||
return attribute.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,19 +52,6 @@ namespace Umbraco.Core
|
||||
public static Attempt<T> TryConvertTo<T>(this object input)
|
||||
{
|
||||
var result = TryConvertTo(input, typeof(T));
|
||||
if (!result.Success)
|
||||
{
|
||||
//just try a straight up conversion
|
||||
try
|
||||
{
|
||||
var converted = (T) input;
|
||||
return new Attempt<T>(true, converted);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new Attempt<T>(e);
|
||||
}
|
||||
}
|
||||
return !result.Success ? Attempt<T>.False : new Attempt<T>(true, (T)result.Result);
|
||||
}
|
||||
|
||||
@@ -85,21 +72,11 @@ namespace Umbraco.Core
|
||||
|
||||
if (!destinationType.IsGenericType || destinationType.GetGenericTypeDefinition() != typeof(Nullable<>))
|
||||
{
|
||||
//TODO: Do a check for destination type being IEnumerable<T> and source type implementing IEnumerable<T> with
|
||||
// the same 'T', then we'd have to find the extension method for the type AsEnumerable() and execute it.
|
||||
|
||||
if (TypeHelper.IsTypeAssignableFrom(destinationType, input.GetType())
|
||||
&& TypeHelper.IsTypeAssignableFrom<IConvertible>(input))
|
||||
{
|
||||
try
|
||||
{
|
||||
var casted = Convert.ChangeType(input, destinationType);
|
||||
return new Attempt<object>(true, casted);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return new Attempt<object>(e);
|
||||
}
|
||||
var casted = Convert.ChangeType(input, destinationType);
|
||||
return new Attempt<object>(true, casted);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,11 @@ namespace Umbraco.Core.ObjectResolution
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
protected override bool SupportsRemove
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
private class LegacyStartupHandlerResolver : ManyObjectsResolverBase<ApplicationEventsResolver, IApplicationStartupHandler>
|
||||
{
|
||||
internal LegacyStartupHandlerResolver(IEnumerable<Type> legacyStartupHandlers)
|
||||
@@ -73,7 +78,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
get { return Values; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,146 +6,124 @@ using System.Web;
|
||||
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class for all lazy many-objects resolvers.
|
||||
/// </summary>
|
||||
/// <typeparam name="TResolver">The type of the concrete resolver class.</typeparam>
|
||||
/// <typeparam name="TResolved">The type of the resolved objects.</typeparam>
|
||||
/// <remarks>
|
||||
/// <para>This is a special case resolver for when types get lazily resolved in order to resolve the actual types. This is useful
|
||||
/// for when there is some processing overhead (i.e. Type finding in assemblies) to return the Types used to instantiate the instances.
|
||||
/// In some these cases we don't want to have to type-find during application startup, only when we need to resolve the instances.</para>
|
||||
/// <para>Important notes about this resolver: it does not support Insert or Remove and therefore does not support any ordering unless
|
||||
/// the types are marked with the WeightedPluginAttribute.</para>
|
||||
/// <summary>
|
||||
/// A base class for lazily resolving types for a resolver
|
||||
/// </summary>
|
||||
/// <typeparam name="TResolver"></typeparam>
|
||||
/// <typeparam name="TResolved"></typeparam>
|
||||
/// <remarks>
|
||||
/// This is a special case resolver for when types get lazily resolved in order to resolve the actual types. This is useful
|
||||
/// for when there is some processing overhead (i.e. Type finding in assemblies) to return the Types used to instantiate the instances.
|
||||
/// In some these cases we don't want to have to type find during application startup, only when we need to resolve the instances.
|
||||
///
|
||||
/// Important notes about this resolver: This does not support Insert or Remove and therefore does not support any ordering unless
|
||||
/// the types are marked with the WeightedPluginAttribute.
|
||||
/// </remarks>
|
||||
internal abstract class LazyManyObjectsResolverBase<TResolver, TResolved> : ManyObjectsResolverBase<TResolver, TResolved>
|
||||
where TResolved : class
|
||||
where TResolver : ResolverBase
|
||||
where TResolver : class
|
||||
{
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LazyManyObjectsResolverBase{TResolver, TResolved}"/> class with an empty list of objects,
|
||||
/// with creation of objects based on an HttpRequest lifetime scope.
|
||||
/// </summary>
|
||||
/// <param name="scope">The lifetime scope of instantiated objects, default is per Application.</param>
|
||||
/// <remarks>If <paramref name="scope"/> is per HttpRequest then there must be a current HttpContext.</remarks>
|
||||
/// <exception cref="InvalidOperationException"><paramref name="scope"/> is per HttpRequest but the current HttpContext is null.</exception>
|
||||
protected LazyManyObjectsResolverBase(ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
|
||||
: base(scope)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LazyManyObjectsResolverBase{TResolver, TResolved}"/> class with an empty list of objects,
|
||||
/// with creation of objects based on an HttpRequest lifetime scope.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The HttpContextBase corresponding to the HttpRequest.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="httpContext"/> is <c>null</c>.</exception>
|
||||
{
|
||||
}
|
||||
|
||||
protected LazyManyObjectsResolverBase(HttpContextBase httpContext)
|
||||
: base(httpContext)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LazyManyObjectsResolverBase{TResolver, TResolved}"/> class with an initial list
|
||||
/// <remarks>If <paramref name="scope"/> is per HttpRequest then there must be a current HttpContext.</remarks>
|
||||
/// <exception cref="InvalidOperationException"><paramref name="scope"/> is per HttpRequest but the current HttpContext is null.</exception>
|
||||
protected LazyManyObjectsResolverBase(IEnumerable<Lazy<Type>> lazyTypeList, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
|
||||
/// <summary>
|
||||
/// Constructor accepting a list of lazy types
|
||||
/// </summary>
|
||||
/// <param name="listOfLazyTypes"></param>
|
||||
/// <param name="scope"></param>
|
||||
protected LazyManyObjectsResolverBase(IEnumerable<Lazy<Type>> listOfLazyTypes, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
|
||||
: this(scope)
|
||||
{
|
||||
AddTypes(lazyTypeList);
|
||||
AddTypes(listOfLazyTypes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LazyManyObjectsResolverBase{TResolver, TResolved}"/> class with an initial list
|
||||
/// of functions producing types, and an optional lifetime scope.
|
||||
/// </summary>
|
||||
/// <param name="typeListProducerList">The list of functions producing types.</param>
|
||||
/// <param name="scope">The lifetime scope of instantiated objects, default is per Application.</param>
|
||||
/// <remarks>If <paramref name="scope"/> is per HttpRequest then there must be a current HttpContext.</remarks>
|
||||
/// <exception cref="InvalidOperationException"><paramref name="scope"/> is per HttpRequest but the current HttpContext is null.</exception>
|
||||
protected LazyManyObjectsResolverBase(Func<IEnumerable<Type>> typeListProducerList, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
|
||||
/// <summary>
|
||||
/// Constructor accepting a delegate to return a list of types
|
||||
/// </summary>
|
||||
/// <param name="typeListDelegate"></param>
|
||||
/// <param name="scope"></param>
|
||||
protected LazyManyObjectsResolverBase(Func<IEnumerable<Type>> typeListDelegate, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
|
||||
: this(scope)
|
||||
{
|
||||
_typeListProducerList.Add(typeListProducerList);
|
||||
_listOfTypeListDelegates.Add(typeListDelegate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LazyManyObjectsResolverBase{TResolver, TResolved}"/> class with an initial list of
|
||||
/// lazy object types, with creation of objects based on an HttpRequest lifetime scope.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The HttpContextBase corresponding to the HttpRequest.</param>
|
||||
/// <param name="lazyTypeList">The list of lazy object types.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="httpContext"/> is <c>null</c>.</exception>
|
||||
protected LazyManyObjectsResolverBase(HttpContextBase httpContext, IEnumerable<Lazy<Type>> lazyTypeList)
|
||||
/// <summary>
|
||||
/// Constructor accepting a list of lazy types
|
||||
/// </summary>
|
||||
/// <param name="httpContext"></param>
|
||||
/// <param name="listOfLazyTypes"></param>
|
||||
protected LazyManyObjectsResolverBase(HttpContextBase httpContext, IEnumerable<Lazy<Type>> listOfLazyTypes)
|
||||
: this(httpContext)
|
||||
{
|
||||
AddTypes(lazyTypeList);
|
||||
AddTypes(listOfLazyTypes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LazyManyObjectsResolverBase{TResolver, TResolved}"/> class with an initial list of
|
||||
/// functions producing types, with creation of objects based on an HttpRequest lifetime scope.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The HttpContextBase corresponding to the HttpRequest.</param>
|
||||
/// <param name="typeListProducerList">The list of functions producing types.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="httpContext"/> is <c>null</c>.</exception>
|
||||
protected LazyManyObjectsResolverBase(HttpContextBase httpContext, Func<IEnumerable<Type>> typeListProducerList)
|
||||
/// <summary>
|
||||
/// Constructor accepting a delegate to return a list of types
|
||||
/// </summary>
|
||||
/// <param name="httpContext"></param>
|
||||
/// <param name="typeListDelegate"></param>
|
||||
protected LazyManyObjectsResolverBase(HttpContextBase httpContext, Func<IEnumerable<Type>> typeListDelegate)
|
||||
: this(httpContext)
|
||||
{
|
||||
_typeListProducerList.Add(typeListProducerList);
|
||||
_listOfTypeListDelegates.Add(typeListDelegate);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private readonly List<Lazy<Type>> _lazyTypeList = new List<Lazy<Type>>();
|
||||
private readonly List<Func<IEnumerable<Type>>> _typeListProducerList = new List<Func<IEnumerable<Type>>>();
|
||||
private readonly List<Type> _excludedTypesList = new List<Type>();
|
||||
|
||||
private readonly List<Func<IEnumerable<Type>>> _listOfTypeListDelegates = new List<Func<IEnumerable<Type>>>();
|
||||
private List<Type> _resolvedTypes = null;
|
||||
private readonly ReaderWriterLockSlim _resolvedTypesLock = new ReaderWriterLockSlim();
|
||||
private readonly ReaderWriterLockSlim _typeResolutionLock = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the resolver has resolved types to create instances from.
|
||||
/// Used for unit tests
|
||||
/// </summary>
|
||||
/// <remarks>To be used in unit tests.</remarks>
|
||||
internal bool HasResolvedTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
using (new ReadLock(_resolvedTypesLock))
|
||||
{
|
||||
return _resolvedTypes != null;
|
||||
}
|
||||
}
|
||||
get { return _resolvedTypes != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of types to create instances from.
|
||||
/// </summary>
|
||||
/// <remarks>When called, will get the types from the lazy list.</remarks>
|
||||
protected override IEnumerable<Type> InstanceTypes
|
||||
/// <summary>
|
||||
/// Once this is called this will resolve all types registered in the lazy list
|
||||
/// </summary>
|
||||
protected override IEnumerable<Type> InstanceTypes
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var lck = new UpgradeableReadLock(_resolvedTypesLock))
|
||||
using (var lck = new UpgradeableReadLock(_typeResolutionLock))
|
||||
{
|
||||
if (_resolvedTypes == null)
|
||||
var lazyTypeList = _lazyTypeList.Select(x => x.Value).ToArray();
|
||||
var listofTypeListDelegates = _listOfTypeListDelegates.SelectMany(x => x()).ToArray();
|
||||
|
||||
//we need to validate each resolved type now since we could not do it before when inserting the lazy delegates
|
||||
if (!HasResolvedTypes)
|
||||
{
|
||||
lck.UpgradeToWriteLock();
|
||||
lck.UpgradeToWriteLock();
|
||||
|
||||
_resolvedTypes = new List<Type>();
|
||||
_resolvedTypes = new List<Type>();
|
||||
|
||||
// get the types by evaluating the lazy & producers
|
||||
var types = new List<Type>();
|
||||
types.AddRange(_lazyTypeList.Select(x => x.Value));
|
||||
types.AddRange(_typeListProducerList.SelectMany(x => x()));
|
||||
|
||||
// we need to validate each resolved type now since we could
|
||||
// not do it before evaluating the lazy & producers
|
||||
foreach (var type in types.Where(x => !_excludedTypesList.Contains(x)))
|
||||
{
|
||||
AddValidAndNoDuplicate(_resolvedTypes, type);
|
||||
}
|
||||
//first iterate the lazy type list
|
||||
foreach (var l in lazyTypeList)
|
||||
{
|
||||
UpdateUniqueList(_resolvedTypes, l);
|
||||
}
|
||||
|
||||
//next iterate the list of list type delegates
|
||||
foreach (var l in listofTypeListDelegates)
|
||||
{
|
||||
UpdateUniqueList(_resolvedTypes, l);
|
||||
}
|
||||
}
|
||||
|
||||
return _resolvedTypes;
|
||||
@@ -153,46 +131,27 @@ namespace Umbraco.Core.ObjectResolution
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that type is valid and not a duplicate
|
||||
/// then appends the type to the end of the list
|
||||
/// </summary>
|
||||
/// <param name="list"></param>
|
||||
/// <param name="type"></param>
|
||||
private void AddValidAndNoDuplicate(List<Type> list, Type type)
|
||||
private void UpdateUniqueList(List<Type> uniqueList, Type toAdd)
|
||||
{
|
||||
EnsureCorrectType(type);
|
||||
if (list.Contains(type))
|
||||
EnsureCorrectType(toAdd);
|
||||
if (uniqueList.Contains(toAdd))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Type {0} is already in the collection of types.", type.FullName));
|
||||
}
|
||||
list.Add(type);
|
||||
throw new InvalidOperationException("The Type " + toAdd + " already exists in the collection");
|
||||
}
|
||||
uniqueList.Add(toAdd);
|
||||
}
|
||||
|
||||
#region Types collection manipulation
|
||||
|
||||
/// <summary>
|
||||
/// Removes types from the list of types, once it has been lazily evaluated, and before actual objects are instanciated.
|
||||
/// </summary>
|
||||
/// <param name="value">The type to remove.</param>
|
||||
public override void RemoveType(Type value)
|
||||
{
|
||||
EnsureSupportsRemove();
|
||||
|
||||
_excludedTypesList.Add(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lazily adds types from lazy types.
|
||||
/// <summary>
|
||||
/// Allows adding of multiple lazy types at once
|
||||
/// </summary>
|
||||
/// <param name="types">The lazy types, to add.</param>
|
||||
/// <param name="types"></param>
|
||||
protected void AddTypes(IEnumerable<Lazy<Type>> types)
|
||||
{
|
||||
EnsureSupportsAdd();
|
||||
EnsureAddSupport();
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (GetWriteLock())
|
||||
EnsureResolutionNotFrozen();
|
||||
|
||||
using (GetWriteLock())
|
||||
{
|
||||
foreach (var t in types)
|
||||
{
|
||||
@@ -202,40 +161,41 @@ namespace Umbraco.Core.ObjectResolution
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lazily adds types from a function producing types.
|
||||
/// Adds a type list delegate to the collection
|
||||
/// </summary>
|
||||
/// <param name="typeListProducer">The functions producing types, to add.</param>
|
||||
public void AddTypeListDelegate(Func<IEnumerable<Type>> typeListProducer)
|
||||
/// <param name="typeListDelegate"></param>
|
||||
public void AddTypeListDelegate(Func<IEnumerable<Type>> typeListDelegate)
|
||||
{
|
||||
EnsureSupportsAdd();
|
||||
EnsureAddSupport();
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (GetWriteLock())
|
||||
EnsureResolutionNotFrozen();
|
||||
|
||||
using (GetWriteLock())
|
||||
{
|
||||
_typeListProducerList.Add(typeListProducer);
|
||||
_listOfTypeListDelegates.Add(typeListDelegate);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lazily adds a type from a lazy type.
|
||||
/// Adds a lazy type to the list
|
||||
/// </summary>
|
||||
/// <param name="value">The lazy type, to add.</param>
|
||||
/// <param name="value"></param>
|
||||
public void AddType(Lazy<Type> value)
|
||||
{
|
||||
EnsureSupportsAdd();
|
||||
EnsureAddSupport();
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (GetWriteLock())
|
||||
EnsureResolutionNotFrozen();
|
||||
|
||||
using (GetWriteLock())
|
||||
{
|
||||
_lazyTypeList.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lazily adds a type from an actual type.
|
||||
/// Converts the static type added to a lazy type and adds it to the internal list
|
||||
/// </summary>
|
||||
/// <param name="value">The actual type, to add.</param>
|
||||
/// <remarks>The type is converted to a lazy type.</remarks>
|
||||
/// <param name="value"></param>
|
||||
public override void AddType(Type value)
|
||||
{
|
||||
AddType(new Lazy<Type>(() => value));
|
||||
@@ -246,27 +206,30 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// </summary>
|
||||
public override void Clear()
|
||||
{
|
||||
EnsureSupportsClear();
|
||||
EnsureClearSupport();
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (GetWriteLock())
|
||||
EnsureResolutionNotFrozen();
|
||||
|
||||
using (GetWriteLock())
|
||||
{
|
||||
_lazyTypeList.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Types collection manipulation support
|
||||
/// <summary>
|
||||
/// Does not support removal
|
||||
/// </summary>
|
||||
protected override bool SupportsRemove
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <c>false</c> value indicating that the resolver does NOT support inserting types.
|
||||
/// Does not support insert
|
||||
/// </summary>
|
||||
protected override bool SupportsInsert
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,10 @@ using System.Threading;
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class for old legacy factories such as the DataTypeFactory or CacheResolverFactory.
|
||||
/// A base resolver used for old legacy factories such as the DataTypeFactory or CacheResolverFactory.
|
||||
/// </summary>
|
||||
/// <typeparam name="TResolver">The type of the concrete resolver class.</typeparam>
|
||||
/// <typeparam name="TResolved">The type of the resolved objects.</typeparam>
|
||||
/// <typeparam name="TResolver"></typeparam>
|
||||
/// <typeparam name="TResolved"> </typeparam>
|
||||
/// <remarks>
|
||||
/// This class contains basic functionality to mimic the functionality in these old factories since they all return
|
||||
/// transient objects (though this should be changed) and the method GetById needs to lookup a type to an ID and since
|
||||
@@ -19,67 +19,67 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// </remarks>
|
||||
internal abstract class LegacyTransientObjectsResolver<TResolver, TResolved> : LazyManyObjectsResolverBase<TResolver, TResolved>
|
||||
where TResolved : class
|
||||
where TResolver : ResolverBase
|
||||
where TResolver : class
|
||||
{
|
||||
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
|
||||
private ConcurrentDictionary<Guid, Type> _id2type;
|
||||
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LegacyTransientObjectsResolver{TResolver, TResolved}"/> class with an initial list of object types.
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="value">A function returning the list of object types.</param>
|
||||
/// <param name="types"></param>
|
||||
/// <remarks>
|
||||
/// We are creating Transient instances (new instances each time) because this is how the legacy code worked and
|
||||
/// I don't want to muck anything up by changing them to application based instances.
|
||||
/// TODO: However, it would make much more sense to do this and would speed up the application plus this would make the GetById method much easier.
|
||||
/// </remarks>
|
||||
protected LegacyTransientObjectsResolver(Func<IEnumerable<Type>> value)
|
||||
: base(value, ObjectLifetimeScope.Transient) // new objects every time
|
||||
{ }
|
||||
protected LegacyTransientObjectsResolver(Func<IEnumerable<Type>> types)
|
||||
: base(types, ObjectLifetimeScope.Transient) // new objects every time
|
||||
{
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns the unique identifier of the type of a specified object.
|
||||
/// Maintains a list of Ids and their types when first call to CacheResolvers or GetById occurs, this is used
|
||||
/// in order to return a single object by id without instantiating the entire type stack.
|
||||
/// </summary>
|
||||
/// <param name="value">The object.</param>
|
||||
/// <returns>The unique identifier of the type of <paramref name="value"/>.</returns>
|
||||
protected abstract Guid GetUniqueIdentifier(TResolved value);
|
||||
private ConcurrentDictionary<Guid, Type> _trackIdToType;
|
||||
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new instance for the type identified by its unique type identifier.
|
||||
/// method to return the unique id for type T
|
||||
/// </summary>
|
||||
/// <param name="id">The type identifier.</param>
|
||||
/// <returns>The value of the type uniquely identified by <paramref name="id"/>.</returns>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
protected abstract Guid GetUniqueIdentifier(TResolved obj);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a new TResolved instance by id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public TResolved GetById(Guid id)
|
||||
{
|
||||
EnsureIsInitialized();
|
||||
return !_id2type.ContainsKey(id)
|
||||
EnsureIdsAreTracked();
|
||||
return !_trackIdToType.ContainsKey(id)
|
||||
? null
|
||||
: PluginManager.Current.CreateInstance<TResolved>(_id2type[id]);
|
||||
: PluginManager.Current.CreateInstance<TResolved>(_trackIdToType[id]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates the identifiers-to-types dictionnary.
|
||||
/// Populates the ids -> Type dictionary to allow us to instantiate a type by Id since these legacy types doesn't contain any metadata
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This allow us to instantiate a type by ID since these legacy types doesn't contain any metadata.</para>
|
||||
/// <para>We instanciate all types once to get their unique identifier, then build the dictionary so that
|
||||
/// when GetById is called, we can instanciate a single object.</para>
|
||||
/// </remarks>
|
||||
protected void EnsureIsInitialized()
|
||||
protected void EnsureIdsAreTracked()
|
||||
{
|
||||
using (var l = new UpgradeableReadLock(_lock))
|
||||
{
|
||||
if (_id2type == null)
|
||||
if (_trackIdToType == null)
|
||||
{
|
||||
l.UpgradeToWriteLock();
|
||||
|
||||
_id2type = new ConcurrentDictionary<Guid, Type>();
|
||||
foreach (var value in Values)
|
||||
_trackIdToType = new ConcurrentDictionary<Guid, Type>();
|
||||
foreach (var v in Values)
|
||||
{
|
||||
_id2type.TryAdd(GetUniqueIdentifier(value), value.GetType());
|
||||
_trackIdToType.TryAdd(GetUniqueIdentifier(v), v.GetType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -3,11 +3,10 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Core.Macros;
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Macros
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// A resolver to return all IMacroGuiRendering objects
|
||||
@@ -25,7 +24,9 @@ namespace Umbraco.Core.Macros
|
||||
/// <param name="macroEditors"></param>
|
||||
internal MacroFieldEditorsResolver(Func<IEnumerable<Type>> macroEditors)
|
||||
: base(macroEditors, ObjectLifetimeScope.Transient)
|
||||
{ }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IMacroGuiRendering"/> implementations.
|
||||
@@ -6,102 +6,82 @@ using System.Web;
|
||||
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class for all many-objects resolvers.
|
||||
/// </summary>
|
||||
/// <typeparam name="TResolver">The type of the concrete resolver class.</typeparam>
|
||||
/// <typeparam name="TResolved">The type of the resolved objects.</typeparam>
|
||||
public abstract class ManyObjectsResolverBase<TResolver, TResolved> : ResolverBase<TResolver>
|
||||
where TResolved : class
|
||||
where TResolver : ResolverBase
|
||||
internal abstract class ManyObjectsResolverBase<TResolver, TResolved> : ResolverBase<TResolver>
|
||||
where TResolved : class
|
||||
where TResolver : class
|
||||
{
|
||||
private IEnumerable<TResolved> _applicationInstances = null;
|
||||
private List<TResolved> _applicationInstances = null;
|
||||
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
|
||||
private readonly string _httpContextKey;
|
||||
private readonly List<Type> _instanceTypes = new List<Type>();
|
||||
private IEnumerable<TResolved> _sortedValues = null;
|
||||
|
||||
private int _defaultPluginWeight = 10;
|
||||
private readonly List<Type> _instanceTypes = new List<Type>();
|
||||
|
||||
#region Constructors
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManyObjectsResolverBase{TResolver, TResolved}"/> class with an empty list of objects,
|
||||
/// and an optional lifetime scope.
|
||||
/// Initializes a new instance of the <see cref="ManyObjectsResolverBase{TResolver, TResolved}"/> class with an empty list of objects.
|
||||
/// </summary>
|
||||
/// <param name="scope">The lifetime scope of instantiated objects, default is per Application.</param>
|
||||
/// <remarks>If <paramref name="scope"/> is per HttpRequest then there must be a current HttpContext.</remarks>
|
||||
/// <exception cref="InvalidOperationException"><paramref name="scope"/> is per HttpRequest but the current HttpContext is null.</exception>
|
||||
/// <param name="scope">The lifetime scope of instantiated objects, default is per Application</param>
|
||||
protected ManyObjectsResolverBase(ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
|
||||
{
|
||||
CanResolveBeforeFrozen = false;
|
||||
if (scope == ObjectLifetimeScope.HttpRequest)
|
||||
{
|
||||
if (HttpContext.Current == null)
|
||||
{
|
||||
throw new InvalidOperationException("Use alternative constructor accepting a HttpContextBase object in order to set the lifetime scope to HttpRequest when HttpContext.Current is null");
|
||||
|
||||
}
|
||||
CurrentHttpContext = new HttpContextWrapper(HttpContext.Current);
|
||||
}
|
||||
|
||||
LifetimeScope = scope;
|
||||
if (scope == ObjectLifetimeScope.HttpRequest)
|
||||
_httpContextKey = this.GetType().FullName;
|
||||
_instanceTypes = new List<Type>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManyObjectsResolverBase{TResolver, TResolved}"/> class with an empty list of objects,
|
||||
/// Initializes a new instance of the <see cref="ManyObjectsResolverBase{TResolver, TResolved}"/> class with an empty list of objects.
|
||||
/// with creation of objects based on an HttpRequest lifetime scope.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The HttpContextBase corresponding to the HttpRequest.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="httpContext"/> is <c>null</c>.</exception>
|
||||
/// <param name="httpContext"></param>
|
||||
protected ManyObjectsResolverBase(HttpContextBase httpContext)
|
||||
{
|
||||
CanResolveBeforeFrozen = false;
|
||||
if (httpContext == null)
|
||||
throw new ArgumentNullException("httpContext");
|
||||
if (httpContext == null) throw new ArgumentNullException("httpContext");
|
||||
LifetimeScope = ObjectLifetimeScope.HttpRequest;
|
||||
_httpContextKey = this.GetType().FullName;
|
||||
CurrentHttpContext = httpContext;
|
||||
_instanceTypes = new List<Type>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManyObjectsResolverBase{TResolver, TResolved}"/> class with an initial list of object types,
|
||||
/// and an optional lifetime scope.
|
||||
/// Initializes a new instance of the <see cref="ManyObjectsResolverBase{TResolver, TResolved}"/> class with an initial list of objects.
|
||||
/// </summary>
|
||||
/// <param name="value">The list of object types.</param>
|
||||
/// <param name="scope">The lifetime scope of instantiated objects, default is per Application.</param>
|
||||
/// <remarks>If <paramref name="scope"/> is per HttpRequest then there must be a current HttpContext.</remarks>
|
||||
/// <exception cref="InvalidOperationException"><paramref name="scope"/> is per HttpRequest but the current HttpContext is null.</exception>
|
||||
/// <param name="value">The list of objects.</param>
|
||||
/// <param name="scope">If set to true will resolve singleton objects which will be created once for the lifetime of the application</param>
|
||||
protected ManyObjectsResolverBase(IEnumerable<Type> value, ObjectLifetimeScope scope = ObjectLifetimeScope.Application)
|
||||
: this(scope)
|
||||
{
|
||||
_instanceTypes = value.ToList();
|
||||
_instanceTypes = new List<Type>(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManyObjectsResolverBase{TResolver, TResolved}"/> class with an initial list of objects,
|
||||
/// Initializes a new instance of the <see cref="ManyObjectsResolverBase{TResolver, TResolved}"/> class with an initial list of objects
|
||||
/// with creation of objects based on an HttpRequest lifetime scope.
|
||||
/// </summary>
|
||||
/// <param name="httpContext">The HttpContextBase corresponding to the HttpRequest.</param>
|
||||
/// <param name="value">The list of object types.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="httpContext"/> is <c>null</c>.</exception>
|
||||
/// <param name="httpContext"></param>
|
||||
/// <param name="value"></param>
|
||||
protected ManyObjectsResolverBase(HttpContextBase httpContext, IEnumerable<Type> value)
|
||||
: this(httpContext)
|
||||
{
|
||||
_instanceTypes = value.ToList();
|
||||
_instanceTypes = new List<Type>(value);
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the resolver can resolve objects before resolution is frozen.
|
||||
/// used internally for special resolvers to be able to resolve objects before resolution is frozen.
|
||||
/// </summary>
|
||||
/// <remarks>This is false by default and is used for some special internal resolvers.</remarks>
|
||||
internal bool CanResolveBeforeFrozen { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of types to create instances from.
|
||||
/// Returns the list of Types registered that instances will be created from
|
||||
/// </summary>
|
||||
protected virtual IEnumerable<Type> InstanceTypes
|
||||
{
|
||||
@@ -109,137 +89,114 @@ namespace Umbraco.Core.ObjectResolution
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="HttpContextBase"/> used to initialize this object, if any.
|
||||
/// Returns the Current HttpContextBase used to construct this object if one exists.
|
||||
/// If one exists then the LifetimeScope will be ObjectLifetimeScope.HttpRequest
|
||||
/// </summary>
|
||||
/// <remarks>If not null, then <c>LifetimeScope</c> will be <c>ObjectLifetimeScope.HttpRequest</c>.</remarks>
|
||||
protected HttpContextBase CurrentHttpContext { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the lifetime scope of resolved objects.
|
||||
/// Returns the ObjectLifetimeScope for created objects
|
||||
/// </summary>
|
||||
protected ObjectLifetimeScope LifetimeScope { get; private set; }
|
||||
|
||||
private int _defaultPluginWeight = 10;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resolved object instances, sorted by weight.
|
||||
/// Used in conjunction with GetSortedValues and WeightedPluginAttribute, if any of the objects
|
||||
/// being resolved do not contain the WeightedPluginAttribute then this will be the default weight applied
|
||||
/// to the object.
|
||||
/// </summary>
|
||||
/// <returns>The sorted resolved object instances.</returns>
|
||||
/// <remarks>
|
||||
/// <para>The order is based upon the <c>WeightedPluginAttribute</c> and <c>DefaultPluginWeight</c>.</para>
|
||||
/// <para>Weights are sorted ascendingly (lowest weights come first).</para>
|
||||
/// </remarks>
|
||||
protected IEnumerable<TResolved> GetSortedValues()
|
||||
{
|
||||
if (_sortedValues == null)
|
||||
{
|
||||
var values = Values.ToList();
|
||||
values.Sort((f1, f2) => GetObjectWeight(f1).CompareTo(GetObjectWeight(f2)));
|
||||
_sortedValues = values;
|
||||
}
|
||||
return _sortedValues;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default type weight.
|
||||
/// </summary>
|
||||
/// <remarks>Determines the weight of types that do not have a <c>WeightedPluginAttribute</c> set on
|
||||
/// them, when calling <c>GetSortedValues</c>.</remarks>
|
||||
protected virtual int DefaultPluginWeight
|
||||
{
|
||||
get { return _defaultPluginWeight; }
|
||||
set { _defaultPluginWeight = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the weight of an object for user with GetSortedValues
|
||||
/// </summary>
|
||||
/// <param name="o"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual int GetObjectWeight(object o)
|
||||
/// <summary>
|
||||
/// If a resolver requries that objects are resolved with a specific order using the WeightedPluginAttribute
|
||||
/// then this method should be used instead of the Values property.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected IEnumerable<TResolved> GetSortedValues()
|
||||
{
|
||||
var type = o.GetType();
|
||||
var attr = type.GetCustomAttribute<WeightedPluginAttribute>(true);
|
||||
return attr == null ? DefaultPluginWeight : attr.Weight;
|
||||
}
|
||||
var vals = Values.ToList();
|
||||
//ensure they are sorted
|
||||
vals.Sort((f1, f2) =>
|
||||
{
|
||||
Func<object, int> getWeight = o =>
|
||||
{
|
||||
var weightAttribute = f1.GetType().GetCustomAttribute<WeightedPluginAttribute>(true);
|
||||
return weightAttribute != null ? weightAttribute.Weight : DefaultPluginWeight;
|
||||
};
|
||||
return getWeight(f1).CompareTo(getWeight(f2));
|
||||
});
|
||||
return vals;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resolved object instances.
|
||||
/// Returns the list of new object instances.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException"><c>CanResolveBeforeFrozen</c> is false, and resolution is not frozen.</exception>
|
||||
protected IEnumerable<TResolved> Values
|
||||
{
|
||||
get
|
||||
{
|
||||
// ensure we can
|
||||
if (!CanResolveBeforeFrozen)
|
||||
Resolution.EnsureIsFrozen();
|
||||
|
||||
// note: we apply .ToArray() to the output of CreateInstance() because that is an IEnumerable that
|
||||
// comes from the PluginManager we want to be _sure_ that it's not a Linq of some sort, but the
|
||||
// instances have actually been instanciated when we return.
|
||||
{
|
||||
//We cannot return values unless resolution is locked
|
||||
if (!CanResolveBeforeFrozen && !Resolution.IsFrozen)
|
||||
throw new InvalidOperationException("Values cannot be returned until Resolution is frozen");
|
||||
|
||||
switch (LifetimeScope)
|
||||
{
|
||||
case ObjectLifetimeScope.HttpRequest:
|
||||
// create new instances per HttpContext
|
||||
//create new instances per HttpContext, this means we'll lazily create them and once created, cache them in the HttpContext
|
||||
//create new instances per application, this means we'll lazily create them and once created, cache them
|
||||
using (var l = new UpgradeableReadLock(_lock))
|
||||
{
|
||||
// create if not already there
|
||||
if (CurrentHttpContext.Items[_httpContextKey] == null)
|
||||
//check if the items contain the key (based on the full type name)
|
||||
if (CurrentHttpContext.Items[this.GetType().FullName] == null)
|
||||
{
|
||||
l.UpgradeToWriteLock();
|
||||
CurrentHttpContext.Items[_httpContextKey] = CreateInstances().ToArray();
|
||||
//add the items to the context items (based on full type name)
|
||||
CurrentHttpContext.Items[this.GetType().FullName] = new List<TResolved>(CreateInstances());
|
||||
}
|
||||
return (TResolved[])CurrentHttpContext.Items[_httpContextKey];
|
||||
return (List<TResolved>)CurrentHttpContext.Items[this.GetType().FullName];
|
||||
}
|
||||
|
||||
case ObjectLifetimeScope.Application:
|
||||
// create new instances per application
|
||||
//create new instances per application, this means we'll lazily create them and once created, cache them
|
||||
using(var l = new UpgradeableReadLock(_lock))
|
||||
{
|
||||
// create if not already there
|
||||
if (_applicationInstances == null)
|
||||
{
|
||||
l.UpgradeToWriteLock();
|
||||
_applicationInstances = CreateInstances().ToArray();
|
||||
_applicationInstances = new List<TResolved>(CreateInstances());
|
||||
}
|
||||
return _applicationInstances;
|
||||
}
|
||||
|
||||
case ObjectLifetimeScope.Transient:
|
||||
default:
|
||||
// create new instances each time
|
||||
return CreateInstances().ToArray();
|
||||
//create new instances each time
|
||||
return CreateInstances();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the object instances for the types contained in the types collection.
|
||||
/// </summary>
|
||||
/// <returns>A list of objects of type <typeparamref name="TResolved"/>.</returns>
|
||||
protected virtual IEnumerable<TResolved> CreateInstances()
|
||||
{
|
||||
return PluginManager.Current.CreateInstances<TResolved>(InstanceTypes);
|
||||
}
|
||||
|
||||
#region Types collection manipulation
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a type.
|
||||
/// </summary>
|
||||
/// <param name="value">The type to remove.</param>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support removing types, or
|
||||
/// the type is not a valid type for the resolver.</exception>
|
||||
public virtual void RemoveType(Type value)
|
||||
{
|
||||
EnsureSupportsRemove();
|
||||
EnsureRemoveSupport();
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (var l = new UpgradeableReadLock(_lock))
|
||||
EnsureResolutionNotFrozen();
|
||||
|
||||
using (GetWriteLock())
|
||||
{
|
||||
EnsureCorrectType(value);
|
||||
|
||||
l.UpgradeToWriteLock();
|
||||
_instanceTypes.Remove(value);
|
||||
}
|
||||
}
|
||||
@@ -247,231 +204,114 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// <summary>
|
||||
/// Removes a type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to remove.</typeparam>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support removing types, or
|
||||
/// the type is not a valid type for the resolver.</exception>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public void RemoveType<T>()
|
||||
where T : TResolved
|
||||
{
|
||||
RemoveType(typeof(T));
|
||||
RemoveType(typeof (T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds types.
|
||||
/// protected method allow the inheritor to add many types at once
|
||||
/// </summary>
|
||||
/// <param name="types">The types to add.</param>
|
||||
/// <remarks>The types are appended at the end of the list.</remarks>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
|
||||
/// a type is not a valid type for the resolver, or a type is already in the collection of types.</exception>
|
||||
/// <param name="types"></param>
|
||||
protected void AddTypes(IEnumerable<Type> types)
|
||||
{
|
||||
EnsureSupportsAdd();
|
||||
EnsureAddSupport();
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (new WriteLock(_lock))
|
||||
EnsureResolutionNotFrozen();
|
||||
|
||||
using (GetWriteLock())
|
||||
{
|
||||
foreach(var t in types)
|
||||
{
|
||||
EnsureCorrectType(t);
|
||||
if (_instanceTypes.Contains(t))
|
||||
if (InstanceTypes.Contains(t))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Type {0} is already in the collection of types.", t.FullName));
|
||||
}
|
||||
throw new InvalidOperationException("The Type " + t + " already exists in the collection");
|
||||
};
|
||||
_instanceTypes.Add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a type.
|
||||
/// Adds a Type to the end of the list.
|
||||
/// </summary>
|
||||
/// <param name="value">The type to add.</param>
|
||||
/// <remarks>The type is appended at the end of the list.</remarks>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
|
||||
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
|
||||
/// <param name="value">The object to be added.</param>
|
||||
public virtual void AddType(Type value)
|
||||
{
|
||||
EnsureSupportsAdd();
|
||||
EnsureAddSupport();
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (var l = new UpgradeableReadLock(_lock))
|
||||
EnsureResolutionNotFrozen();
|
||||
|
||||
using (GetWriteLock())
|
||||
{
|
||||
EnsureCorrectType(value);
|
||||
if (_instanceTypes.Contains(value))
|
||||
if (InstanceTypes.Contains(value))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Type {0} is already in the collection of types.", value.FullName));
|
||||
}
|
||||
|
||||
l.UpgradeToWriteLock();
|
||||
throw new InvalidOperationException("The Type " + value + " already exists in the collection");
|
||||
};
|
||||
_instanceTypes.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a type.
|
||||
/// Adds a Type to the end of the list.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to add.</typeparam>
|
||||
/// <remarks>The type is appended at the end of the list.</remarks>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support adding types, or
|
||||
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public void AddType<T>()
|
||||
where T : TResolved
|
||||
{
|
||||
AddType(typeof(T));
|
||||
AddType(typeof (T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the list of types.
|
||||
/// Clears the list.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support clearing types.</exception>
|
||||
public virtual void Clear()
|
||||
{
|
||||
EnsureSupportsClear();
|
||||
EnsureClearSupport();
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (new WriteLock(_lock))
|
||||
EnsureResolutionNotFrozen();
|
||||
|
||||
using (GetWriteLock())
|
||||
{
|
||||
_instanceTypes.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a type at the specified index.
|
||||
/// Inserts a Type at the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index at which the type should be inserted.</param>
|
||||
/// <param name="value">The type to insert.</param>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
|
||||
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is out of range.</exception>
|
||||
/// <param name="index">The zero-based index at which the object should be inserted.</param>
|
||||
/// <param name="value">The object to insert.</param>
|
||||
public virtual void InsertType(int index, Type value)
|
||||
{
|
||||
EnsureSupportsInsert();
|
||||
EnsureInsertSupport();
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (var l = new UpgradeableReadLock(_lock))
|
||||
EnsureResolutionNotFrozen();
|
||||
|
||||
using (var l = GetWriteLock())
|
||||
{
|
||||
EnsureCorrectType(value);
|
||||
if (_instanceTypes.Contains(value))
|
||||
if (InstanceTypes.Contains(value))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Type {0} is already in the collection of types.", value.FullName));
|
||||
}
|
||||
throw new InvalidOperationException("The Type " + value + " already exists in the collection");
|
||||
};
|
||||
|
||||
l.UpgradeToWriteLock();
|
||||
_instanceTypes.Insert(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a type at the beginning of the list.
|
||||
/// </summary>
|
||||
/// <param name="value">The type to insert.</param>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
|
||||
/// the type is not a valid type for the resolver, or the type is already in the collection of types.</exception>
|
||||
public virtual void InsertType(Type value)
|
||||
{
|
||||
InsertType(0, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a type at the specified index.
|
||||
/// <summary>
|
||||
/// Inserts a Type at the specified index.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to insert.</typeparam>
|
||||
/// <param name="index">The zero-based index at which the type should be inserted.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="index"/> is out of range.</exception>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="index"></param>
|
||||
public void InsertType<T>(int index)
|
||||
where T : TResolved
|
||||
{
|
||||
InsertType(index, typeof(T));
|
||||
InsertType(index, typeof (T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a type at the beginning of the list.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to insert.</typeparam>
|
||||
public void InsertType<T>()
|
||||
where T : TResolved
|
||||
{
|
||||
InsertType(0, typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a type before a specified, already existing type.
|
||||
/// </summary>
|
||||
/// <param name="existingType">The existing type before which to insert.</param>
|
||||
/// <param name="value">The type to insert.</param>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
|
||||
/// one of the types is not a valid type for the resolver, or the existing type is not in the collection,
|
||||
/// or the new type is already in the collection of types.</exception>
|
||||
public virtual void InsertTypeBefore(Type existingType, Type value)
|
||||
{
|
||||
EnsureSupportsInsert();
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (var l = new UpgradeableReadLock(_lock))
|
||||
{
|
||||
EnsureCorrectType(existingType);
|
||||
EnsureCorrectType(value);
|
||||
if (!_instanceTypes.Contains(existingType))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Type {0} is not in the collection of types.", existingType.FullName));
|
||||
}
|
||||
if (_instanceTypes.Contains(value))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Type {0} is already in the collection of types.", value.FullName));
|
||||
}
|
||||
int index = _instanceTypes.IndexOf(existingType);
|
||||
|
||||
l.UpgradeToWriteLock();
|
||||
_instanceTypes.Insert(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inserts a type before a specified, already existing type.
|
||||
/// </summary>
|
||||
/// <typeparam name="TExisting">The existing type before which to insert.</typeparam>
|
||||
/// <typeparam name="T">The type to insert.</typeparam>
|
||||
/// <exception cref="InvalidOperationException">the resolver does not support inserting types, or
|
||||
/// one of the types is not a valid type for the resolver, or the existing type is not in the collection,
|
||||
/// or the new type is already in the collection of types.</exception>
|
||||
public void InsertTypeBefore<TExisting, T>()
|
||||
where TExisting : TResolved
|
||||
where T : TResolved
|
||||
{
|
||||
InsertTypeBefore(typeof(TExisting), typeof(T));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the specified type is already in the collection of types.
|
||||
/// </summary>
|
||||
/// <param name="value">The type to look for.</param>
|
||||
/// <returns>A value indicating whether the type is already in the collection of types.</returns>
|
||||
public virtual bool ContainsType(Type value)
|
||||
{
|
||||
using (new ReadLock(_lock))
|
||||
{
|
||||
return _instanceTypes.Contains(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value indicating whether the specified type is already in the collection of types.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to look for.</typeparam>
|
||||
/// <returns>A value indicating whether the type is already in the collection of types.</returns>
|
||||
public bool ContainsType<T>()
|
||||
where T : TResolved
|
||||
{
|
||||
return ContainsType(typeof(T));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Returns a WriteLock to use when modifying collections
|
||||
/// </summary>
|
||||
@@ -480,96 +320,80 @@ namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
return new WriteLock(_lock);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception if resolution is frozen
|
||||
/// </summary>
|
||||
protected void EnsureResolutionNotFrozen()
|
||||
{
|
||||
if (Resolution.IsFrozen)
|
||||
throw new InvalidOperationException("The type list cannot be modified after resolution has been frozen");
|
||||
}
|
||||
|
||||
#region Type utilities
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that a type is a valid type for the resolver.
|
||||
/// </summary>
|
||||
/// <param name="value">The type to test.</param>
|
||||
/// <exception cref="InvalidOperationException">the type is not a valid type for the resolver.</exception>
|
||||
protected void EnsureCorrectType(Type value)
|
||||
{
|
||||
if (!TypeHelper.IsTypeAssignableFrom<TResolved>(value))
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Type {0} is not an acceptable type for resolver {1}.", value.FullName, this.GetType().FullName));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Types collection manipulation support
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the resolver supports removing types.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">The resolver does not support removing types.</exception>
|
||||
protected void EnsureSupportsRemove()
|
||||
/// <summary>
|
||||
/// Throws an exception if this does not support Remove
|
||||
/// </summary>
|
||||
protected void EnsureRemoveSupport()
|
||||
{
|
||||
if (!SupportsRemove)
|
||||
throw new InvalidOperationException("This resolver does not support removing types");
|
||||
throw new InvalidOperationException("This resolver does not support Removing types");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the resolver supports clearing types.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">The resolver does not support clearing types.</exception>
|
||||
protected void EnsureSupportsClear() {
|
||||
/// <summary>
|
||||
/// Throws an exception if this does not support Clear
|
||||
/// </summary>
|
||||
protected void EnsureClearSupport()
|
||||
{
|
||||
if (!SupportsClear)
|
||||
throw new InvalidOperationException("This resolver does not support clearing types");
|
||||
throw new InvalidOperationException("This resolver does not support Clearing types");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the resolver supports adding types.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">The resolver does not support adding types.</exception>
|
||||
protected void EnsureSupportsAdd()
|
||||
/// <summary>
|
||||
/// Throws an exception if this does not support Add
|
||||
/// </summary>
|
||||
protected void EnsureAddSupport()
|
||||
{
|
||||
if (!SupportsAdd)
|
||||
throw new InvalidOperationException("This resolver does not support adding new types");
|
||||
throw new InvalidOperationException("This resolver does not support Adding new types");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures that the resolver supports inserting types.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">The resolver does not support inserting types.</exception>
|
||||
protected void EnsureSupportsInsert()
|
||||
/// <summary>
|
||||
/// Throws an exception if this does not support insert
|
||||
/// </summary>
|
||||
protected void EnsureInsertSupport()
|
||||
{
|
||||
if (!SupportsInsert)
|
||||
throw new InvalidOperationException("This resolver does not support inserting new types");
|
||||
throw new InvalidOperationException("This resolver does not support Inserting new types");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception if the type is not of the TResolved type
|
||||
/// </summary>
|
||||
/// <param name="t"></param>
|
||||
protected void EnsureCorrectType(Type t)
|
||||
{
|
||||
if (!TypeHelper.IsTypeAssignableFrom<TResolved>(t))
|
||||
throw new InvalidOperationException("The resolver " + this.GetType() + " can only accept types of " + typeof(TResolved) + ". The Type passed in to this method is " + t);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the resolver supports adding types.
|
||||
/// </summary>
|
||||
protected virtual bool SupportsAdd
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the resolver supports inserting types.
|
||||
/// </summary>
|
||||
protected virtual bool SupportsInsert
|
||||
protected virtual bool SupportsInsert
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the resolver supports clearing types.
|
||||
/// </summary>
|
||||
protected virtual bool SupportsClear
|
||||
protected virtual bool SupportsClear
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the resolver supports removing types.
|
||||
/// </summary>
|
||||
protected virtual bool SupportsRemove
|
||||
protected virtual bool SupportsRemove
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,9 @@
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the lifetime scope of resolved objects.
|
||||
/// </summary>
|
||||
public enum ObjectLifetimeScope
|
||||
internal enum ObjectLifetimeScope
|
||||
{
|
||||
/// <summary>
|
||||
/// A per-request object instance is created.
|
||||
/// </summary>
|
||||
HttpRequest,
|
||||
|
||||
/// <summary>
|
||||
/// A single application-wide object instance is created.
|
||||
/// </summary>
|
||||
Application,
|
||||
|
||||
/// <summary>
|
||||
/// A new object instance is created each time one is requested.
|
||||
/// </summary>
|
||||
Transient
|
||||
}
|
||||
}
|
||||
@@ -1,93 +1,30 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the status of objects resolution.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Before resolution is frozen it is possible to access its configuration, but not to get values.</para>
|
||||
/// <para>Once resolution is frozen, it is not possible to access its configuration anymore, but it is possible to get values.</para>
|
||||
/// </remarks>
|
||||
internal static class Resolution
|
||||
{
|
||||
private static readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when resolution is frozen.
|
||||
/// </summary>
|
||||
/// <remarks>Occurs only once, since resolution can be frozen only once.</remarks>
|
||||
|
||||
|
||||
// notes: nothing in Resolving is thread-safe because everything should happen when the app is starting
|
||||
|
||||
internal class Resolution
|
||||
{
|
||||
public static event EventHandler Frozen;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether resolution of objects is frozen.
|
||||
/// Gets a value indicating that resolution is frozen
|
||||
/// </summary>
|
||||
public static bool IsFrozen { get; private set; }
|
||||
/// <remarks>
|
||||
/// The internal setter is normally used for unit tests
|
||||
/// </remarks>
|
||||
public static bool IsFrozen { get; internal set; }
|
||||
|
||||
public static void EnsureIsFrozen()
|
||||
public static void EnsureNotFrozen()
|
||||
{
|
||||
if (!IsFrozen)
|
||||
throw new InvalidOperationException("Resolution is not frozen, it is not yet possible to get values from it.");
|
||||
if (Resolution.IsFrozen)
|
||||
throw new InvalidOperationException("Resolution is frozen. It is not possible to modify resolvers once resolution is frozen.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a disposable object that represents safe access to unfrozen resolution configuration.
|
||||
/// </summary>
|
||||
/// <remarks>Should be used in a <c>using(Resolution.Configuration) { ... }</c> mode.</remarks>
|
||||
public static IDisposable Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
IDisposable l = new WriteLock(_lock);
|
||||
if (Resolution.IsFrozen)
|
||||
{
|
||||
l.Dispose();
|
||||
throw new InvalidOperationException("Resolution is frozen, it is not possible to configure it anymore.");
|
||||
}
|
||||
return l;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a disposable object that reprents dirty access to temporarily unfrozen resolution configuration.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Should not be used.</para>
|
||||
/// <para>Should be used in a <c>using(Resolution.DirtyBackdoorToConfiguration) { ... }</c> mode.</para>
|
||||
/// <para>Because we just lift the frozen state, and we don't actually re-freeze, the <c>Frozen</c> event does not trigger.</para>
|
||||
/// </remarks>
|
||||
internal static IDisposable DirtyBackdoorToConfiguration
|
||||
{
|
||||
get { return new DirtyBackdoor(); }
|
||||
}
|
||||
|
||||
// keep the class here because it needs write-access to Resolution.IsFrozen
|
||||
private class DirtyBackdoor : IDisposable
|
||||
{
|
||||
private static readonly System.Threading.ReaderWriterLockSlim _dirtyLock = new ReaderWriterLockSlim();
|
||||
|
||||
private IDisposable _lock;
|
||||
private bool _frozen;
|
||||
|
||||
public DirtyBackdoor()
|
||||
{
|
||||
_lock = new WriteLock(_dirtyLock);
|
||||
_frozen = Resolution.IsFrozen;
|
||||
Resolution.IsFrozen = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Resolution.IsFrozen = _frozen;
|
||||
_lock.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Freezes resolution.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">resolution is already frozen.</exception>
|
||||
public static void Freeze()
|
||||
{
|
||||
if (Resolution.IsFrozen)
|
||||
@@ -97,15 +34,5 @@ namespace Umbraco.Core.ObjectResolution
|
||||
if (Frozen != null)
|
||||
Frozen(null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets resolution, ie unfreezes it and clears Frozen event.
|
||||
/// </summary>
|
||||
/// <remarks>To be used in unit tests.</remarks>
|
||||
internal static void Reset()
|
||||
{
|
||||
IsFrozen = false;
|
||||
Frozen = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,57 +3,24 @@ using System.Threading;
|
||||
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// Base non-generic class for resolvers
|
||||
/// </summary>
|
||||
public abstract class ResolverBase
|
||||
{
|
||||
protected ResolverBase(Action resetAction)
|
||||
{
|
||||
//add itself to the internal collection
|
||||
ResolverCollection.Add(this, resetAction);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The base class for all resolvers.
|
||||
/// base class for resolvers which declare a singleton accessor
|
||||
/// </summary>
|
||||
/// <typeparam name="TResolver">The type of the concrete resolver class.</typeparam>
|
||||
/// <remarks>Provides singleton management to all resolvers.</remarks>
|
||||
public abstract class ResolverBase<TResolver> : ResolverBase
|
||||
where TResolver : ResolverBase
|
||||
/// <typeparam name="TResolver"></typeparam>
|
||||
internal abstract class ResolverBase<TResolver>
|
||||
where TResolver : class
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The underlying singleton object instance
|
||||
/// </summary>
|
||||
static TResolver _resolver;
|
||||
|
||||
/// <summary>
|
||||
/// The lock for the singleton.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Though resharper says this is in error, it is actually correct. We want a different lock object for each generic type.
|
||||
/// See this for details: http://confluence.jetbrains.net/display/ReSharper/Static+field+in+generic+type
|
||||
/// </remarks>
|
||||
static readonly ReaderWriterLockSlim ResolversLock = new ReaderWriterLockSlim();
|
||||
|
||||
/// <summary>
|
||||
/// Constructor set the reset action for the underlying object
|
||||
/// </summary>
|
||||
protected ResolverBase()
|
||||
: base(() => Reset())
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the resolver singleton instance.
|
||||
static TResolver _resolver;
|
||||
|
||||
/// <summary>
|
||||
/// The lock for the singleton
|
||||
/// </summary>
|
||||
/// <remarks>The value can be set only once, and cannot be read before it has been set.</remarks>
|
||||
/// <exception cref="InvalidOperationException">value is read before it has been set, or value is set again once it has already been set.</exception>
|
||||
/// <exception cref="ArgumentNullException">value is <c>null</c>.</exception>
|
||||
/// <remarks>
|
||||
/// Though resharper says this is in error, it is actually correct. We want a different lock object for each generic type.
|
||||
/// See this for details: http://confluence.jetbrains.net/display/ReSharper/Static+field+in+generic+type
|
||||
/// </remarks>
|
||||
static readonly ReaderWriterLockSlim ResolversLock = new ReaderWriterLockSlim();
|
||||
|
||||
public static TResolver Current
|
||||
{
|
||||
get
|
||||
@@ -61,67 +28,30 @@ namespace Umbraco.Core.ObjectResolution
|
||||
using (new ReadLock(ResolversLock))
|
||||
{
|
||||
if (_resolver == null)
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Current has not been initialized on {0}. You must initialize Current before trying to read it.",
|
||||
typeof(TResolver).FullName));
|
||||
throw new InvalidOperationException("Current has not been initialized on " + typeof(TResolver) + ". You must initialize Current before trying to read it.");
|
||||
return _resolver;
|
||||
}
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
using (Resolution.Configuration)
|
||||
using (new WriteLock(ResolversLock))
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
if (_resolver != null)
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Current has already been initialized on {0}. It is not possible to re-initialize Current once it has been initialized.",
|
||||
typeof(TResolver).FullName));
|
||||
throw new InvalidOperationException("Current has already been initialized. It is not possible to re-initialize Current once it has been initialized.");
|
||||
_resolver = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether a the singleton nstance has been set.
|
||||
/// </summary>
|
||||
/// <remarks>To be used in unit tests.</remarks>
|
||||
internal static bool HasCurrent
|
||||
{
|
||||
get
|
||||
{
|
||||
using (new ReadLock(ResolversLock))
|
||||
{
|
||||
return _resolver != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets the resolver singleton instance to null.
|
||||
/// used in unit tests to reset current to null
|
||||
/// </summary>
|
||||
/// <remarks>To be used in unit tests.</remarks>
|
||||
/// <param name="resetResolution">By default this is true because we always need to reset resolution before we reset a resolver, however in some insanely rare cases like unit testing you might not want to do this.</param>
|
||||
internal static void Reset(bool resetResolution = true)
|
||||
internal static void Reset()
|
||||
{
|
||||
|
||||
//In order to reset a resolver, we always must reset the resolution
|
||||
if (resetResolution)
|
||||
{
|
||||
Resolution.Reset();
|
||||
}
|
||||
|
||||
//ensure its removed from the collection
|
||||
ResolverCollection.Remove(_resolver);
|
||||
|
||||
using (Resolution.Configuration)
|
||||
using (new WriteLock(ResolversLock))
|
||||
{
|
||||
_resolver = null;
|
||||
}
|
||||
|
||||
_resolver = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// Simply used to track all ManyObjectsResolverBase instances so that we can
|
||||
/// reset them all at once really easily.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Normally we'd use TypeFinding for this but because many of the resolvers are internal this won't work.
|
||||
/// We'd rather not keep a static list of them so we'll dynamically add to this list based on the base
|
||||
/// class of the ManyObjectsResolverBase.
|
||||
/// </remarks>
|
||||
internal static class ResolverCollection
|
||||
{
|
||||
private static readonly ConcurrentDictionary<ResolverBase, Action> Resolvers = new ConcurrentDictionary<ResolverBase, Action>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of resolvers created
|
||||
/// </summary>
|
||||
internal static int Count
|
||||
{
|
||||
get { return Resolvers.Count; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets all resolvers
|
||||
/// </summary>
|
||||
internal static void ResetAll()
|
||||
{
|
||||
//take out each item from the bag and reset it
|
||||
var keys = Resolvers.Keys.ToArray();
|
||||
foreach (var k in keys)
|
||||
{
|
||||
Action resetAction;
|
||||
while (Resolvers.TryRemove(k, out resetAction))
|
||||
{
|
||||
//call the reset action for the resolver
|
||||
resetAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is called when the static Reset method or a ResolverBase{T} is called.
|
||||
/// </summary>
|
||||
internal static void Remove(ResolverBase resolver)
|
||||
{
|
||||
if (resolver == null) return;
|
||||
Action action;
|
||||
Resolvers.TryRemove(resolver, out action);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a resolver to the collection
|
||||
/// </summary>
|
||||
/// <param name="resolver"></param>
|
||||
/// <param name="resetAction"></param>
|
||||
/// <remarks>
|
||||
/// This is called when the creation of a ResolverBase occurs
|
||||
/// </remarks>
|
||||
internal static void Add(ResolverBase resolver, Action resetAction)
|
||||
{
|
||||
Resolvers.TryAdd(resolver, resetAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,123 +1,59 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// The base class for all single-object resolvers.
|
||||
/// A Resolver to return and set a Single registered object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TResolver">The type of the concrete resolver class.</typeparam>
|
||||
/// <typeparam name="TResolved">The type of the resolved object.</typeparam>
|
||||
/// <typeparam name="TResolved"></typeparam>
|
||||
/// <typeparam name="TResolver"> </typeparam>
|
||||
/// <remarks>
|
||||
/// Resolves "single" objects ie objects for which there is only one application-wide instance, such as the MVC Controller factory.
|
||||
/// Used for 'singly' registered objects. An example is like the MVC Controller Factory, only one exists application wide and it can
|
||||
/// be get/set.
|
||||
/// </remarks>
|
||||
public abstract class SingleObjectResolverBase<TResolver, TResolved> : ResolverBase<TResolver>
|
||||
internal abstract class SingleObjectResolverBase<TResolver, TResolved> : ResolverBase<TResolver>
|
||||
where TResolved : class
|
||||
where TResolver : ResolverBase
|
||||
where TResolver : class
|
||||
{
|
||||
private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
|
||||
private readonly bool _canBeNull;
|
||||
private TResolved _value;
|
||||
TResolved _resolved;
|
||||
readonly bool _canBeNull;
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="SingleObjectResolverBase{TResolver, TResolved}"/> class.
|
||||
/// </summary>
|
||||
/// <remarks>By default <c>CanBeNull</c> is false, so <c>Value</c> has to be initialized before being read,
|
||||
/// otherwise an exception will be thrown when reading it.</remarks>
|
||||
protected SingleObjectResolverBase()
|
||||
: this(false)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="SingleObjectResolverBase{TResolver, TResolved}"/> class with an instance of the resolved object.
|
||||
/// </summary>
|
||||
/// <param name="value">An instance of the resolved object.</param>
|
||||
/// <remarks>By default <c>CanBeNull</c> is false, so <c>value</c> has to be non-null, or <c>Value</c> has to be
|
||||
/// initialized before being accessed, otherwise an exception will be thrown when reading it.</remarks>
|
||||
protected SingleObjectResolverBase(TResolved value)
|
||||
: this(false)
|
||||
{
|
||||
_value = value;
|
||||
_resolved = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="SingleObjectResolverBase{TResolver, TResolved}"/> class with a value indicating whether the resolved object instance can be null.
|
||||
/// </summary>
|
||||
/// <param name="canBeNull">A value indicating whether the resolved object instance can be null.</param>
|
||||
/// <remarks>If <c>CanBeNull</c> is false, <c>Value</c> has to be initialized before being read,
|
||||
/// otherwise an exception will be thrown when reading it.</remarks>
|
||||
protected SingleObjectResolverBase(bool canBeNull)
|
||||
{
|
||||
_canBeNull = canBeNull;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of the <see cref="SingleObjectResolverBase{TResolver, TResolved}"/> class with an instance of the resolved object,
|
||||
/// and a value indicating whether that instance can be null.
|
||||
/// </summary>
|
||||
/// <param name="value">An instance of the resolved object.</param>
|
||||
/// <param name="canBeNull">A value indicating whether the resolved object instance can be null.</param>
|
||||
/// <remarks>If <c>CanBeNull</c> is false, <c>value</c> has to be non-null, or <c>Value</c> has to be initialized before being read,
|
||||
/// otherwise an exception will be thrown when reading it.</remarks>
|
||||
protected SingleObjectResolverBase(TResolved value, bool canBeNull)
|
||||
{
|
||||
_value = value;
|
||||
_resolved = value;
|
||||
_canBeNull = canBeNull;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the resolved object instance can be null.
|
||||
/// Gets/sets the value of the object
|
||||
/// </summary>
|
||||
public bool CanBeNull
|
||||
{
|
||||
get { return _canBeNull; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the resolved object instance is null.
|
||||
/// </summary>
|
||||
public bool HasValue
|
||||
{
|
||||
get { return _value != null; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the resolved object instance.
|
||||
/// </summary>
|
||||
/// <remarks></remarks>
|
||||
/// <exception cref="ArgumentNullException">value is set to null, but cannot be null (<c>CanBeNull</c> is <c>false</c>).</exception>
|
||||
/// <exception cref="InvalidOperationException">value is read and is null, but cannot be null (<c>CanBeNull</c> is <c>false</c>),
|
||||
/// or value is set (read) and resolution is (not) frozen.</exception>
|
||||
protected TResolved Value
|
||||
{
|
||||
get
|
||||
{
|
||||
Resolution.EnsureIsFrozen();
|
||||
using (new ReadLock(_lock))
|
||||
{
|
||||
if (!_canBeNull && _value == null)
|
||||
throw new InvalidOperationException(string.Format(
|
||||
"Resolver {0} requires a value, and none was supplied.", this.GetType().FullName));
|
||||
|
||||
return _value;
|
||||
}
|
||||
return _resolved;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
using (Resolution.Configuration)
|
||||
using (var l = new UpgradeableReadLock(_lock))
|
||||
{
|
||||
if (!_canBeNull && value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
|
||||
l.UpgradeToWriteLock();
|
||||
_value = value;
|
||||
}
|
||||
if (!_canBeNull && value == null)
|
||||
throw new ArgumentNullException("value");
|
||||
_resolved = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,23 +3,17 @@ using System;
|
||||
namespace Umbraco.Core.ObjectResolution
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates the relative weight of a resolved object type.
|
||||
/// Some many object resolvers require that the objects that they resolve have weights applied to them so that
|
||||
/// the objects are returned in a sorted order, this attribute is used in these scenarios.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
|
||||
internal class WeightedPluginAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WeightedPluginAttribute"/> class with a weight.
|
||||
/// </summary>
|
||||
/// <param name="weight">The object type weight.</param>
|
||||
public WeightedPluginAttribute(int weight)
|
||||
{
|
||||
Weight = weight;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the weight of the object type.
|
||||
/// </summary>
|
||||
public int Weight { get; private set; }
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user