This commit is contained in:
Tobe O 2017-09-24 15:43:14 -04:00
parent 3fcb195d8c
commit e3e25453b6
12 changed files with 344 additions and 313 deletions

View file

@ -2,10 +2,18 @@
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="7b89ff1e-1260-4dcf-9c3d-345de0471ea1" name="Default" comment=""> <list default="true" id="7b89ff1e-1260-4dcf-9c3d-345de0471ea1" name="Default" comment="">
<change type="NEW" beforePath="" afterPath="$PROJECT_DIR$/lib/src/http/injection.dart" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/.idea/workspace.xml" afterPath="$PROJECT_DIR$/.idea/workspace.xml" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/CHANGELOG.md" afterPath="$PROJECT_DIR$/CHANGELOG.md" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/CHANGELOG.md" afterPath="$PROJECT_DIR$/CHANGELOG.md" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/angel_base.dart" afterPath="$PROJECT_DIR$/lib/src/http/angel_base.dart" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/controller.dart" afterPath="$PROJECT_DIR$/lib/src/http/controller.dart" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/request_context.dart" afterPath="$PROJECT_DIR$/lib/src/http/request_context.dart" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/routable.dart" afterPath="$PROJECT_DIR$/lib/src/http/routable.dart" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/server.dart" afterPath="$PROJECT_DIR$/lib/src/http/server.dart" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/lib/src/http/server.dart" afterPath="$PROJECT_DIR$/lib/src/http/server.dart" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/pubspec.yaml" afterPath="$PROJECT_DIR$/pubspec.yaml" /> <change type="MODIFICATION" beforePath="$PROJECT_DIR$/pubspec.yaml" afterPath="$PROJECT_DIR$/pubspec.yaml" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/precontained_test.dart" afterPath="$PROJECT_DIR$/test/precontained_test.dart" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/server_test.dart" afterPath="$PROJECT_DIR$/test/server_test.dart" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/test/util_test.dart" afterPath="$PROJECT_DIR$/test/util_test.dart" />
</list> </list>
<ignored path="$PROJECT_DIR$/.tmp/" /> <ignored path="$PROJECT_DIR$/.tmp/" />
<ignored path="$PROJECT_DIR$/temp/" /> <ignored path="$PROJECT_DIR$/temp/" />
@ -28,47 +36,50 @@
</component> </component>
<component name="FileEditorManager"> <component name="FileEditorManager">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="375"> <leaf SIDE_TABS_SIZE_LIMIT_KEY="375">
<file leaf-file-name="pubspec.yaml" pinned="false" current-in-tab="false"> <file leaf-file-name="request_context.dart" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/pubspec.yaml"> <entry file="file://$PROJECT_DIR$/lib/src/http/request_context.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="15"> <state relative-caret-position="249">
<caret line="1" column="22" lean-forward="false" selection-start-line="1" selection-start-column="22" selection-end-line="1" selection-end-column="22" /> <caret line="43" column="63" lean-forward="false" selection-start-line="43" selection-start-column="63" selection-end-line="43" selection-end-column="63" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="encoders_buffer_test.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/test/encoders_buffer_test.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="197">
<caret line="84" column="18" lean-forward="true" selection-start-line="84" selection-start-column="18" selection-end-line="84" selection-end-column="18" />
<folding />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="server.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/src/http/server.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="263">
<caret line="528" column="18" lean-forward="false" selection-start-line="528" selection-start-column="18" selection-end-line="528" selection-end-column="18" />
<folding> <folding>
<element signature="e#38#58#0" expanded="true" /> <element signature="e#47#67#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="CHANGELOG.md" pinned="false" current-in-tab="true"> <file leaf-file-name="controller.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/CHANGELOG.md"> <entry file="file://$PROJECT_DIR$/lib/src/http/controller.dart">
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]"> <provider selected="true" editor-type-id="text-editor">
<state split_layout="SPLIT"> <state relative-caret-position="-786">
<first_editor relative-caret-position="30"> <caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<caret line="2" column="72" lean-forward="false" selection-start-line="2" selection-start-column="72" selection-end-line="2" selection-end-column="72" /> <folding>
<folding /> <element signature="e#42#62#0" expanded="true" />
</first_editor> </folding>
<second_editor /> </state>
</provider>
</entry>
</file>
<file leaf-file-name="routable.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/src/http/routable.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-1166">
<caret line="13" column="0" lean-forward="true" selection-start-line="13" selection-start-column="0" selection-end-line="13" selection-end-column="0" />
<folding>
<element signature="e#40#60#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="service.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/src/http/service.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#39#59#0" expanded="true" />
</folding>
</state> </state>
</provider> </provider>
</entry> </entry>
@ -76,35 +87,13 @@
<file leaf-file-name="response_context.dart" pinned="false" current-in-tab="false"> <file leaf-file-name="response_context.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/lib/src/http/response_context.dart"> <entry file="file://$PROJECT_DIR$/lib/src/http/response_context.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-618"> <state relative-caret-position="6345">
<caret line="432" column="10" lean-forward="false" selection-start-line="432" selection-start-column="10" selection-end-line="432" selection-end-column="10" /> <caret line="432" column="10" lean-forward="false" selection-start-line="432" selection-start-column="10" selection-end-line="432" selection-end-column="10" />
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
</file> </file>
<file leaf-file-name="main.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/performance/hello/main.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="165">
<caret line="14" column="20" lean-forward="false" selection-start-line="14" selection-start-column="20" selection-end-line="14" selection-end-column="20" />
<folding>
<element signature="e#75#92#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
</file>
<file leaf-file-name="hooked_test.dart" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/test/hooked_test.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="360">
<caret line="29" column="0" lean-forward="false" selection-start-line="29" selection-start-column="0" selection-end-line="32" selection-end-column="6" />
<folding />
</state>
</provider>
</entry>
</file>
</leaf> </leaf>
</component> </component>
<component name="FileTemplateManagerImpl"> <component name="FileTemplateManagerImpl">
@ -116,10 +105,6 @@
</component> </component>
<component name="FindInProjectRecents"> <component name="FindInProjectRecents">
<findStrings> <findStrings>
<find>handleContaine</find>
<find>_handlerC</find>
<find>angel(</find>
<find>depre</find>
<find>deprecated</find> <find>deprecated</find>
<find>close!</find> <find>close!</find>
<find>close(</find> <find>close(</find>
@ -146,6 +131,10 @@
<find>handleRequ</find> <find>handleRequ</find>
<find>aNGEL(</find> <find>aNGEL(</find>
<find>Routa</find> <find>Routa</find>
<find>properties</find>
<find>noSuchM</find>
<find>preInj</find>
<find>REQU</find>
</findStrings> </findStrings>
<replaceStrings> <replaceStrings>
<replace>_isClosed</replace> <replace>_isClosed</replace>
@ -167,6 +156,7 @@
<dir>C:\Users\thosa\Source\Angel\framework\lib\src\http</dir> <dir>C:\Users\thosa\Source\Angel\framework\lib\src\http</dir>
<dir>C:\Users\thosa\Source\Angel\framework\test</dir> <dir>C:\Users\thosa\Source\Angel\framework\test</dir>
<dir>$PROJECT_DIR$/lib</dir> <dir>$PROJECT_DIR$/lib</dir>
<dir>$PROJECT_DIR$/lib/src</dir>
</dirStrings> </dirStrings>
</component> </component>
<component name="Git.Settings"> <component name="Git.Settings">
@ -180,7 +170,6 @@
<component name="IdeDocumentHistory"> <component name="IdeDocumentHistory">
<option name="CHANGED_PATHS"> <option name="CHANGED_PATHS">
<list> <list>
<option value="$PROJECT_DIR$/lib/src/http/memory_service.dart" />
<option value="$PROJECT_DIR$/test/precontained_test.dart" /> <option value="$PROJECT_DIR$/test/precontained_test.dart" />
<option value="$PROJECT_DIR$/test/general_test.dart" /> <option value="$PROJECT_DIR$/test/general_test.dart" />
<option value="$PROJECT_DIR$/README.md" /> <option value="$PROJECT_DIR$/README.md" />
@ -196,7 +185,6 @@
<option value="$PROJECT_DIR$/lib/src/safe_stream_controller.dart" /> <option value="$PROJECT_DIR$/lib/src/safe_stream_controller.dart" />
<option value="$PROJECT_DIR$/lib/src/extensible.dart" /> <option value="$PROJECT_DIR$/lib/src/extensible.dart" />
<option value="$PROJECT_DIR$/test/util_test.dart" /> <option value="$PROJECT_DIR$/test/util_test.dart" />
<option value="$PROJECT_DIR$/lib/src/http/angel_base.dart" />
<option value="$PROJECT_DIR$/performance/hello/raw.dart" /> <option value="$PROJECT_DIR$/performance/hello/raw.dart" />
<option value="$PROJECT_DIR$/performance/hello/angel.md" /> <option value="$PROJECT_DIR$/performance/hello/angel.md" />
<option value="$PROJECT_DIR$/performance/hello/raw.md" /> <option value="$PROJECT_DIR$/performance/hello/raw.md" />
@ -205,13 +193,11 @@
<option value="$PROJECT_DIR$/test/routing_test.dart" /> <option value="$PROJECT_DIR$/test/routing_test.dart" />
<option value="$PROJECT_DIR$/tool/travis.sh" /> <option value="$PROJECT_DIR$/tool/travis.sh" />
<option value="$PROJECT_DIR$/test/repeat_request_test.dart" /> <option value="$PROJECT_DIR$/test/repeat_request_test.dart" />
<option value="$PROJECT_DIR$/lib/src/http/controller.dart" />
<option value="$PROJECT_DIR$/test/all.dart" /> <option value="$PROJECT_DIR$/test/all.dart" />
<option value="$PROJECT_DIR$/lib/src/http/metadata.dart" /> <option value="$PROJECT_DIR$/lib/src/http/metadata.dart" />
<option value="$PROJECT_DIR$/lib/src/http/fatal_error.dart" /> <option value="$PROJECT_DIR$/lib/src/http/fatal_error.dart" />
<option value="$PROJECT_DIR$/lib/src/http/angel_http_exception.dart" /> <option value="$PROJECT_DIR$/lib/src/http/angel_http_exception.dart" />
<option value="$PROJECT_DIR$/lib/angel_framework.dart" /> <option value="$PROJECT_DIR$/lib/angel_framework.dart" />
<option value="$PROJECT_DIR$/lib/src/http/request_context.dart" />
<option value="$PROJECT_DIR$/lib/hooks.dart" /> <option value="$PROJECT_DIR$/lib/hooks.dart" />
<option value="$PROJECT_DIR$/lib/src/http/base_middleware.dart" /> <option value="$PROJECT_DIR$/lib/src/http/base_middleware.dart" />
<option value="$PROJECT_DIR$/lib/src/fast_name_from_symbol.dart" /> <option value="$PROJECT_DIR$/lib/src/fast_name_from_symbol.dart" />
@ -227,10 +213,14 @@
<option value="$PROJECT_DIR$/test/streaming_test.dart" /> <option value="$PROJECT_DIR$/test/streaming_test.dart" />
<option value="$PROJECT_DIR$/lib/src/http/routable.dart" /> <option value="$PROJECT_DIR$/lib/src/http/routable.dart" />
<option value="$PROJECT_DIR$/performance/hello/main.dart" /> <option value="$PROJECT_DIR$/performance/hello/main.dart" />
<option value="$PROJECT_DIR$/pubspec.yaml" />
<option value="$PROJECT_DIR$/test/encoders_buffer_test.dart" /> <option value="$PROJECT_DIR$/test/encoders_buffer_test.dart" />
<option value="$PROJECT_DIR$/lib/src/http/angel_base.dart" />
<option value="$PROJECT_DIR$/lib/src/http/controller.dart" />
<option value="$PROJECT_DIR$/lib/src/http/injection.dart" />
<option value="$PROJECT_DIR$/lib/src/http/server.dart" /> <option value="$PROJECT_DIR$/lib/src/http/server.dart" />
<option value="$PROJECT_DIR$/CHANGELOG.md" /> <option value="$PROJECT_DIR$/CHANGELOG.md" />
<option value="$PROJECT_DIR$/pubspec.yaml" />
<option value="$PROJECT_DIR$/lib/src/http/request_context.dart" />
</list> </list>
</option> </option>
</component> </component>
@ -265,8 +255,6 @@
</navigator> </navigator>
<panes> <panes>
<pane id="Scratches" /> <pane id="Scratches" />
<pane id="AndroidView" />
<pane id="PackagesPane" />
<pane id="Scope"> <pane id="Scope">
<subPane subId="Project Files"> <subPane subId="Project Files">
<expand> <expand>
@ -311,7 +299,9 @@
<select /> <select />
</subPane> </subPane>
</pane> </pane>
<pane id="PackagesPane" />
<pane id="ProjectPane" /> <pane id="ProjectPane" />
<pane id="AndroidView" />
</panes> </panes>
</component> </component>
<component name="PropertiesComponent"> <component name="PropertiesComponent">
@ -583,7 +573,8 @@
<workItem from="1506050384140" duration="5198000" /> <workItem from="1506050384140" duration="5198000" />
<workItem from="1506088028663" duration="997000" /> <workItem from="1506088028663" duration="997000" />
<workItem from="1506090042437" duration="1751000" /> <workItem from="1506090042437" duration="1751000" />
<workItem from="1506275395906" duration="390000" /> <workItem from="1506275395906" duration="424000" />
<workItem from="1506281553143" duration="624000" />
</task> </task>
<task id="LOCAL-00001" summary="Re-designed exception"> <task id="LOCAL-00001" summary="Re-designed exception">
<created>1481237183504</created> <created>1481237183504</created>
@ -837,13 +828,17 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1506092186428</updated> <updated>1506092186428</updated>
</task> </task>
<option name="localTasksCounter" value="37" /> <task id="LOCAL-00037" summary="+3">
<created>1506275793202</created>
<option name="number" value="00037" />
<option name="presentableId" value="LOCAL-00037" />
<option name="project" value="LOCAL" />
<updated>1506275793202</updated>
</task>
<option name="localTasksCounter" value="38" />
<servers /> <servers />
</component> </component>
<component name="TestHistory"> <component name="TestHistory">
<history-entry file="All_Tests - 2017.09.24 at 13h 52m 04s.xml">
<configuration name="All Tests" configurationId="DartTestRunConfigurationType" />
</history-entry>
<history-entry file="All_Tests - 2017.09.24 at 13h 52m 57s.xml"> <history-entry file="All_Tests - 2017.09.24 at 13h 52m 57s.xml">
<configuration name="All Tests" configurationId="DartTestRunConfigurationType" /> <configuration name="All Tests" configurationId="DartTestRunConfigurationType" />
</history-entry> </history-entry>
@ -859,6 +854,9 @@
<history-entry file="All_Tests - 2017.09.24 at 13h 55m 47s.xml"> <history-entry file="All_Tests - 2017.09.24 at 13h 55m 47s.xml">
<configuration name="All Tests" configurationId="DartTestRunConfigurationType" /> <configuration name="All Tests" configurationId="DartTestRunConfigurationType" />
</history-entry> </history-entry>
<history-entry file="All_Tests - 2017.09.24 at 15h 41m 37s.xml">
<configuration name="All Tests" configurationId="DartTestRunConfigurationType" />
</history-entry>
<history-entry file="only_uses_one_encoder_in_encoders_buffer_test_dart - 2017.09.24 at 13h 55m 12s.xml"> <history-entry file="only_uses_one_encoder_in_encoders_buffer_test_dart - 2017.09.24 at 13h 55m 12s.xml">
<configuration name="only uses one encoder in encoders_buffer_test.dart" configurationId="DartTestRunConfigurationType" /> <configuration name="only uses one encoder in encoders_buffer_test.dart" configurationId="DartTestRunConfigurationType" />
</history-entry> </history-entry>
@ -873,7 +871,7 @@
</history-entry> </history-entry>
</component> </component>
<component name="TimeTrackingManager"> <component name="TimeTrackingManager">
<option name="totallyTimeSpent" value="56170000" /> <option name="totallyTimeSpent" value="56828000" />
</component> </component>
<component name="TodoView"> <component name="TodoView">
<todo-panel id="selected-file"> <todo-panel id="selected-file">
@ -896,14 +894,15 @@
<window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Capture Analysis" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.34188035" sideWeight="0.5035524" order="7" side_tool="true" content_ui="tabs" /> <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.34188035" sideWeight="0.5035524" order="7" side_tool="true" content_ui="tabs" />
<window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Dart Analysis" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32621083" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> <window_info id="Dart Analysis" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.37154695" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.34188035" sideWeight="0.4964476" order="2" side_tool="false" content_ui="tabs" /> <window_info id="Run" active="true" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.34188035" sideWeight="0.4964476" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32905984" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32905984" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.56837606" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" /> <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.48246676" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
<window_info id="Capture Tool" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> <window_info id="Capture Tool" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> <window_info id="Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.26820603" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" /> <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.26820603" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
<window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" /> <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32905984" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" /> <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" /> <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
<window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> <window_info id="UI Designer" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
@ -920,7 +919,6 @@
<window_info id="DB Browser" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32998413" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" /> <window_info id="DB Browser" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32998413" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
<window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" /> <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
<window_info id="Coverage" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="true" content_ui="tabs" /> <window_info id="Coverage" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="3" side_tool="true" content_ui="tabs" />
<window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.32905984" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
</layout> </layout>
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@ -930,7 +928,6 @@
<option name="myLimit" value="2678400000" /> <option name="myLimit" value="2678400000" />
</component> </component>
<component name="VcsManagerConfiguration"> <component name="VcsManagerConfiguration">
<MESSAGE value="+3" />
<MESSAGE value="Coverage start..." /> <MESSAGE value="Coverage start..." />
<MESSAGE value="1.0.3" /> <MESSAGE value="1.0.3" />
<MESSAGE value="+1" /> <MESSAGE value="+1" />
@ -955,14 +952,14 @@
<MESSAGE value="Logging support" /> <MESSAGE value="Logging support" />
<MESSAGE value="Updated `use`" /> <MESSAGE value="Updated `use`" />
<MESSAGE value="+2" /> <MESSAGE value="+2" />
<option name="LAST_COMMIT_MESSAGE" value="+2" /> <MESSAGE value="+3" />
<option name="LAST_COMMIT_MESSAGE" value="+3" />
</component> </component>
<component name="XDebuggerManager"> <component name="XDebuggerManager">
<breakpoint-manager /> <breakpoint-manager />
<watches-manager /> <watches-manager />
</component> </component>
<component name="editorHistoryManager"> <component name="editorHistoryManager">
<entry file="file://$USER_HOME$/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/angel_route-1.0.5/lib/src/extensible.dart" />
<entry file="file://$PROJECT_DIR$/lib/src/extensible.dart" /> <entry file="file://$PROJECT_DIR$/lib/src/extensible.dart" />
<entry file="file://$PROJECT_DIR$/test/precontained_test.dart"> <entry file="file://$PROJECT_DIR$/test/precontained_test.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
@ -1100,13 +1097,6 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/request_context.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="2640">
<caret line="181" column="46" lean-forward="false" selection-start-line="181" selection-start-column="46" selection-end-line="181" selection-end-column="46" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/angel_http_exception.dart" /> <entry file="file://$PROJECT_DIR$/lib/src/http/angel_http_exception.dart" />
<entry file="file://$PROJECT_DIR$/lib/src/http/map_service.dart"> <entry file="file://$PROJECT_DIR$/lib/src/http/map_service.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
@ -1115,20 +1105,6 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/service.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="60">
<caret line="4" column="64" lean-forward="false" selection-start-line="4" selection-start-column="64" selection-end-line="4" selection-end-column="64" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/angel_base.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-133">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/fatal_error.dart" /> <entry file="file://$PROJECT_DIR$/lib/src/http/fatal_error.dart" />
<entry file="file://$PROJECT_DIR$/lib/src/http/hooked_service.dart"> <entry file="file://$PROJECT_DIR$/lib/src/http/hooked_service.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
@ -1186,13 +1162,6 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/controller.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="527">
<caret line="229" column="26" lean-forward="false" selection-start-line="229" selection-start-column="26" selection-end-line="229" selection-end-column="26" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/test/hooked_test.dart"> <entry file="file://$PROJECT_DIR$/test/hooked_test.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="360"> <state relative-caret-position="360">
@ -1205,7 +1174,6 @@
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="271"> <state relative-caret-position="271">
<caret line="361" column="0" lean-forward="true" selection-start-line="361" selection-start-column="0" selection-end-line="361" selection-end-column="0" /> <caret line="361" column="0" lean-forward="true" selection-start-line="361" selection-start-column="0" selection-end-line="361" selection-end-column="0" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
@ -1223,20 +1191,12 @@
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/routable.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="299">
<caret line="97" column="6" lean-forward="false" selection-start-line="97" selection-start-column="6" selection-end-line="97" selection-end-column="6" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/performance/hello/main.dart"> <entry file="file://$PROJECT_DIR$/performance/hello/main.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="165"> <state relative-caret-position="165">
<caret line="14" column="20" lean-forward="false" selection-start-line="14" selection-start-column="20" selection-end-line="14" selection-end-column="20" /> <caret line="14" column="20" lean-forward="false" selection-start-line="14" selection-start-column="20" selection-end-line="14" selection-end-column="20" />
<folding> <folding>
<element signature="e#75#92#0" expanded="true" /> <element signature="e#75#92#0" expanded="false" />
</folding> </folding>
</state> </state>
</provider> </provider>
@ -1245,18 +1205,76 @@
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="225"> <state relative-caret-position="225">
<caret line="57" column="12" lean-forward="false" selection-start-line="57" selection-start-column="12" selection-end-line="57" selection-end-column="12" /> <caret line="57" column="12" lean-forward="false" selection-start-line="57" selection-start-column="12" selection-end-line="57" selection-end-column="12" />
<folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/response_context.dart"> <entry file="file://$PROJECT_DIR$/lib/src/http/response_context.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-618"> <state relative-caret-position="6345">
<caret line="432" column="10" lean-forward="false" selection-start-line="432" selection-start-column="10" selection-end-line="432" selection-end-column="10" /> <caret line="432" column="10" lean-forward="false" selection-start-line="432" selection-start-column="10" selection-end-line="432" selection-end-column="10" />
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/service.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#39#59#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/angel_base.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="195">
<caret line="16" column="0" lean-forward="true" selection-start-line="16" selection-start-column="0" selection-end-line="16" selection-end-column="0" />
<folding />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/controller.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-786">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
<folding>
<element signature="e#42#62#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/CHANGELOG.md">
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]">
<state split_layout="SPLIT">
<first_editor relative-caret-position="30">
<caret line="2" column="57" lean-forward="false" selection-start-line="2" selection-start-column="57" selection-end-line="2" selection-end-column="57" />
<folding />
</first_editor>
<second_editor />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/injection.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="222">
<caret line="59" column="41" lean-forward="true" selection-start-line="59" selection-start-column="41" selection-end-line="59" selection-end-column="41" />
<folding>
<element signature="e#4016#4950#0" expanded="false" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/routable.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-1166">
<caret line="13" column="0" lean-forward="true" selection-start-line="13" selection-start-column="0" selection-end-line="13" selection-end-column="0" />
<folding>
<element signature="e#40#60#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/pubspec.yaml"> <entry file="file://$PROJECT_DIR$/pubspec.yaml">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="15"> <state relative-caret-position="15">
@ -1267,30 +1285,29 @@
</entry> </entry>
<entry file="file://$PROJECT_DIR$/test/encoders_buffer_test.dart"> <entry file="file://$PROJECT_DIR$/test/encoders_buffer_test.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="197"> <state relative-caret-position="903">
<caret line="84" column="18" lean-forward="true" selection-start-line="84" selection-start-column="18" selection-end-line="84" selection-end-column="18" /> <caret line="84" column="18" lean-forward="false" selection-start-line="84" selection-start-column="18" selection-end-line="84" selection-end-column="18" />
<folding /> <folding />
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/lib/src/http/server.dart"> <entry file="file://$PROJECT_DIR$/lib/src/http/server.dart">
<provider selected="true" editor-type-id="text-editor"> <provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="263"> <state relative-caret-position="8085">
<caret line="528" column="18" lean-forward="false" selection-start-line="528" selection-start-column="18" selection-end-line="528" selection-end-column="18" /> <caret line="539" column="8" lean-forward="false" selection-start-line="539" selection-start-column="8" selection-end-line="539" selection-end-column="8" />
<folding> <folding>
<element signature="e#38#58#0" expanded="true" /> <element signature="e#38#58#0" expanded="true" />
</folding> </folding>
</state> </state>
</provider> </provider>
</entry> </entry>
<entry file="file://$PROJECT_DIR$/CHANGELOG.md"> <entry file="file://$PROJECT_DIR$/lib/src/http/request_context.dart">
<provider selected="true" editor-type-id="split-provider[text-editor;markdown-preview-editor]"> <provider selected="true" editor-type-id="text-editor">
<state split_layout="SPLIT"> <state relative-caret-position="249">
<first_editor relative-caret-position="30"> <caret line="43" column="63" lean-forward="false" selection-start-line="43" selection-start-column="63" selection-end-line="43" selection-end-column="63" />
<caret line="2" column="72" lean-forward="false" selection-start-line="2" selection-start-column="72" selection-end-line="2" selection-end-column="72" /> <folding>
<folding /> <element signature="e#47#67#0" expanded="true" />
</first_editor> </folding>
<second_editor />
</state> </state>
</provider> </provider>
</entry> </entry>

View file

@ -1,3 +1,7 @@
# 1.1.0-alpha+4
* Made `injections` in `RequestContext` private.
* Renamed `properties` in `AngelBase` to `configuration`.
# 1.1.0-alpha+3 # 1.1.0-alpha+3
* Fixed a bug where `encoders` would cause a malformed response to be sent. * Fixed a bug where `encoders` would cause a malformed response to be sent.
* Fixed a bug where `encoders` would not always use the correct encoder. * Fixed a bug where `encoders` would not always use the correct encoder.

View file

@ -13,7 +13,7 @@ typedef Future<String> ViewGenerator(String path, [Map data]);
class AngelBase extends Routable { class AngelBase extends Routable {
Container _container = new Container(); Container _container = new Container();
final Map properties = {}; final Map configuration = {};
/// When set to true, the request body will not be parsed /// When set to true, the request body will not be parsed
/// automatically. You can call `req.parse()` manually, /// automatically. You can call `req.parse()` manually,
@ -33,18 +33,18 @@ class AngelBase extends Routable {
ViewGenerator viewGenerator = (String view, [Map data]) async => ViewGenerator viewGenerator = (String view, [Map data]) async =>
"No view engine has been configured yet."; "No view engine has been configured yet.";
operator [](key) => properties[key]; operator [](key) => configuration[key];
operator []=(key, value) => properties[key] = value; operator []=(key, value) => configuration[key] = value;
noSuchMethod(Invocation invocation) { noSuchMethod(Invocation invocation) {
if (invocation.memberName != null) { if (invocation.memberName != null) {
String name = fastNameFromSymbol(invocation.memberName); String name = fastNameFromSymbol(invocation.memberName);
if (invocation.isMethod) { if (invocation.isMethod) {
return Function.apply(properties[name], invocation.positionalArguments, return Function.apply(configuration[name], invocation.positionalArguments,
invocation.namedArguments); invocation.namedArguments);
} else if (invocation.isGetter) { } else if (invocation.isGetter) {
return properties[name]; return configuration[name];
} }
} }

View file

@ -8,34 +8,7 @@ import 'metadata.dart';
import 'request_context.dart'; import 'request_context.dart';
import 'response_context.dart'; import 'response_context.dart';
import 'routable.dart'; import 'routable.dart';
import 'server.dart' show Angel, preInject; import 'server.dart' show Angel;
const List<Type> _primitiveTypes = const [String, int, num, double, Null];
/// Contains a list of the data required for a DI-enabled method to run.
///
/// This improves performance by removing the necessity to reflect a method
/// every time it is requested.
///
/// Regular request handlers can also skip DI entirely, lowering response time
/// and memory use.
class InjectionRequest {
/// Optional, typed data that can be passed to a DI-enabled method.
final Map<String, Type> named;
/// A list of the arguments required for a DI-enabled method to run.
final List required;
/// A list of the arguments that can be null in a DI-enabled method.
final List<String> optional;
const InjectionRequest.constant({this.named, this.required, this.optional});
InjectionRequest()
: named = {},
required = [],
optional = [];
}
/// Supports grouping routes with shared functionality. /// Supports grouping routes with shared functionality.
class Controller { class Controller {
@ -144,90 +117,3 @@ class Controller {
.map((m) => m.reflectee) .map((m) => m.reflectee)
.firstWhere((r) => r is Expose, orElse: () => null); .firstWhere((r) => r is Expose, orElse: () => null);
} }
/// Shortcut for calling [preInject], and then [handleContained].
///
/// Use this to instantly create a request handler for a DI-enabled method.
RequestHandler createDynamicHandler(handler,
{Iterable<String> optional: const []}) {
var injection = preInject(handler);
injection.optional.addAll(optional ?? []);
return handleContained(handler, injection);
}
/// Handles a request with a DI-enabled handler.
RequestHandler handleContained(handler, InjectionRequest injection) {
return (RequestContext req, ResponseContext res) async {
List args = [];
void inject(requirement) {
var propFromApp;
if (requirement == RequestContext) {
args.add(req);
} else if (requirement == ResponseContext) {
args.add(res);
} else if (requirement is String) {
if (req.params.containsKey(requirement)) {
args.add(req.params[requirement]);
} else if (req.injections.containsKey(requirement))
args.add(req.injections[requirement]);
else if (req.properties.containsKey(requirement))
args.add(req.properties[requirement]);
else if ((propFromApp = req.app.findProperty(requirement)) != null)
args.add(propFromApp);
else if (injection.optional.contains(requirement))
args.add(null);
else {
throw new ArgumentError(
"Cannot resolve parameter '$requirement' within handler.");
}
} else if (requirement is List &&
requirement.length == 2 &&
requirement.first is String &&
requirement.last is Type) {
String key = requirement.first;
Type type = requirement.last;
if (req.params.containsKey(key) ||
req.injections.containsKey(key) ||
req.properties.containsKey(key) ||
req.app.properties.containsKey(key) ||
_primitiveTypes.contains(type)) {
inject(key);
} else
inject(type);
} else if (requirement is Type && requirement != dynamic) {
if (req.injections.containsKey(requirement))
args.add(req.injections[requirement]);
else
args.add(req.app.container.make(requirement));
} else {
throw new ArgumentError(
'$requirement cannot be injected into a request handler.');
}
}
Map<Symbol, dynamic> named = {};
injection.required.forEach(inject);
injection.named.forEach((k, v) {
var name = new Symbol(k);
if (req.params.containsKey(k))
named[name] = v;
else if (req.injections.containsKey(k))
named[name] = v;
else if (req.injections.containsKey(v) && v != dynamic)
named[name] = v;
else {
try {
named[name] = req.app.container.make(v);
} catch (e) {
named[name] = null;
}
}
});
var result = Function.apply(handler, args, named);
return result is Future ? await result : result;
};
}

150
lib/src/http/injection.dart Normal file
View file

@ -0,0 +1,150 @@
part of angel_framework.http.request_context;
const List<Type> _primitiveTypes = const [String, int, num, double, Null];
/// Shortcut for calling [preInject], and then [handleContained].
///
/// Use this to instantly create a request handler for a DI-enabled method.
RequestHandler createDynamicHandler(handler,
{Iterable<String> optional: const []}) {
var injection = preInject(handler);
injection.optional.addAll(optional ?? []);
return handleContained(handler, injection);
}
/// Handles a request with a DI-enabled handler.
RequestHandler handleContained(handler, InjectionRequest injection) {
return (RequestContext req, ResponseContext res) async {
List args = [];
void inject(requirement) {
var propFromApp;
if (requirement == RequestContext) {
args.add(req);
} else if (requirement == ResponseContext) {
args.add(res);
} else if (requirement is String) {
if (req.params.containsKey(requirement)) {
args.add(req.params[requirement]);
} else if (req._injections.containsKey(requirement))
args.add(req._injections[requirement]);
else if (req.properties.containsKey(requirement))
args.add(req.properties[requirement]);
else if ((propFromApp = req.app.findProperty(requirement)) != null)
args.add(propFromApp);
else if (injection.optional.contains(requirement))
args.add(null);
else {
throw new ArgumentError(
"Cannot resolve parameter '$requirement' within handler.");
}
} else if (requirement is List &&
requirement.length == 2 &&
requirement.first is String &&
requirement.last is Type) {
String key = requirement.first;
Type type = requirement.last;
if (req.params.containsKey(key) ||
req._injections.containsKey(key) ||
req.properties.containsKey(key) ||
req.app.configuration.containsKey(key) ||
_primitiveTypes.contains(type)) {
inject(key);
} else
inject(type);
} else if (requirement is Type && requirement != dynamic) {
if (req._injections.containsKey(requirement))
args.add(req._injections[requirement]);
else
args.add(req.app.container.make(requirement));
} else {
throw new ArgumentError(
'$requirement cannot be injected into a request handler.');
}
}
Map<Symbol, dynamic> named = {};
injection.required.forEach(inject);
injection.named.forEach((k, v) {
var name = new Symbol(k);
if (req.params.containsKey(k))
named[name] = v;
else if (req._injections.containsKey(k))
named[name] = v;
else if (req._injections.containsKey(v) && v != dynamic)
named[name] = v;
else {
try {
named[name] = req.app.container.make(v);
} catch (e) {
named[name] = null;
}
}
});
var result = Function.apply(handler, args, named);
return result is Future ? await result : result;
};
}
/// Contains a list of the data required for a DI-enabled method to run.
///
/// This improves performance by removing the necessity to reflect a method
/// every time it is requested.
///
/// Regular request handlers can also skip DI entirely, lowering response time
/// and memory use.
class InjectionRequest {
/// Optional, typed data that can be passed to a DI-enabled method.
final Map<String, Type> named;
/// A list of the arguments required for a DI-enabled method to run.
final List required;
/// A list of the arguments that can be null in a DI-enabled method.
final List<String> optional;
const InjectionRequest.constant({this.named, this.required, this.optional});
InjectionRequest()
: named = {},
required = [],
optional = [];
}
/// Predetermines what needs to be injected for a handler to run.
InjectionRequest preInject(Function handler) {
var injection = new InjectionRequest();
ClosureMirror closureMirror = reflect(handler);
if (closureMirror.function.parameters.isEmpty) return injection;
// Load parameters
for (var parameter in closureMirror.function.parameters) {
var name = MirrorSystem.getName(parameter.simpleName);
var type = parameter.type.reflectedType;
if (!parameter.isNamed) {
if (parameter.isOptional) injection.optional.add(name);
if (type == RequestContext || type == ResponseContext) {
injection.required.add(type);
} else if (name == 'req') {
injection.required.add(RequestContext);
} else if (name == 'res') {
injection.required.add(ResponseContext);
} else if (type == dynamic) {
injection.required.add(name);
} else {
injection.required.add([name, type]);
}
} else {
injection.named[name] = type;
}
}
return injection;
}

View file

@ -2,10 +2,14 @@ library angel_framework.http.request_context;
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:mirrors';
import 'package:body_parser/body_parser.dart'; import 'package:body_parser/body_parser.dart';
import 'package:charcode/charcode.dart'; import 'package:charcode/charcode.dart';
import '../fast_name_from_symbol.dart'; import '../fast_name_from_symbol.dart';
import 'response_context.dart';
import 'routable.dart';
import 'server.dart' show Angel; import 'server.dart' show Angel;
part 'injection.dart';
/// A convenience wrapper around an incoming HTTP request. /// A convenience wrapper around an incoming HTTP request.
@proxy @proxy
@ -35,8 +39,10 @@ class RequestContext {
/// The requested hostname. /// The requested hostname.
String get hostname => io.headers.value(HttpHeaders.HOST); String get hostname => io.headers.value(HttpHeaders.HOST);
/// A [Map] of values that should be DI'd. final Map _injections = {};
final Map injections = {};
/// A [Map] of singletons injected via [inject]. *Read-only*.
Map get injections => new Map.unmodifiable(_injections);
/// The underlying [HttpRequest] instance underneath this context. /// The underlying [HttpRequest] instance underneath this context.
HttpRequest get io => _io; HttpRequest get io => _io;
@ -181,14 +187,14 @@ class RequestContext {
return ctx; return ctx;
} }
/// Grabs an object by key or type from [params], [injections], or /// Grabs an object by key or type from [params], [_injections], or
/// [app].container. Use this to perform dependency injection /// [app].container. Use this to perform dependency injection
/// within a service hook. /// within a service hook.
T grab<T>(key) { T grab<T>(key) {
if (params.containsKey(key)) if (params.containsKey(key))
return params[key]; return params[key];
else if (injections.containsKey(key)) else if (_injections.containsKey(key))
return injections[key]; return _injections[key];
else if (properties.containsKey(key)) else if (properties.containsKey(key))
return properties[key]; return properties[key];
else { else {
@ -206,9 +212,9 @@ class RequestContext {
} }
} }
/// Shorthand to add to [injections]. /// Shorthand to add to [_injections].
void inject(type, value) { void inject(type, value) {
injections[type] = value; _injections[type] = value;
} }
/// Returns `true` if the client's `Accept` header indicates that the given [contentType] is considered a valid response. /// Returns `true` if the client's `Accept` header indicates that the given [contentType] is considered a valid response.

View file

@ -37,7 +37,7 @@ RequestMiddleware waterfall(List handlers) {
class Routable extends Router { class Routable extends Router {
final Map<Pattern, Controller> _controllers = {}; final Map<Pattern, Controller> _controllers = {};
final Map<Pattern, Service> _services = {}; final Map<Pattern, Service> _services = {};
final Map properties = {}; final Map configuration = {};
Routable({bool debug: false}) : super(debug: debug); Routable({bool debug: false}) : super(debug: debug);
@ -134,9 +134,9 @@ class Routable extends Router {
// Also copy properties... // Also copy properties...
if (router is Routable) { if (router is Routable) {
Map copiedProperties = new Map.from(router.properties); Map copiedProperties = new Map.from(router.configuration);
for (String propertyName in copiedProperties.keys) { for (String propertyName in copiedProperties.keys) {
properties.putIfAbsent("$middlewarePrefix$propertyName", configuration.putIfAbsent("$middlewarePrefix$propertyName",
() => copiedMiddleware[propertyName]); () => copiedMiddleware[propertyName]);
} }
} }

View file

@ -3,7 +3,6 @@ library angel_framework.http.server;
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:mirrors';
import 'package:angel_http_exception/angel_http_exception.dart'; import 'package:angel_http_exception/angel_http_exception.dart';
import 'package:angel_route/angel_route.dart' hide Extensible; import 'package:angel_route/angel_route.dart' hide Extensible;
import 'package:charcode/charcode.dart'; import 'package:charcode/charcode.dart';
@ -290,7 +289,8 @@ class Angel extends AngelBase {
Future<RequestContext> createRequestContext(HttpRequest request) { Future<RequestContext> createRequestContext(HttpRequest request) {
return RequestContext.from(request, this).then((req) { return RequestContext.from(request, this).then((req) {
return req..injections.addAll(_injections ?? {}); _injections.forEach(req.inject);
return req;
}); });
} }
@ -309,7 +309,7 @@ class Angel extends AngelBase {
/// Attempts to find a property by the given name within this application. /// Attempts to find a property by the given name within this application.
findProperty(key) { findProperty(key) {
if (properties.containsKey(key)) return properties[key]; if (configuration.containsKey(key)) return configuration[key];
return parent != null ? parent.findProperty(key) : null; return parent != null ? parent.findProperty(key) : null;
} }
@ -538,10 +538,13 @@ class Angel extends AngelBase {
return finalizers.then((_) => request.response.close()).then((_) { return finalizers.then((_) => request.response.close()).then((_) {
if (logger != null) { if (logger != null) {
var sw = req.injections[Stopwatch]; var sw = req.grab<Stopwatch>(Stopwatch);
sw?.stop();
logger.info( if (sw.isRunning) {
"${res.statusCode} ${req.method} ${req.uri} (${sw?.elapsedMilliseconds ?? 'unknown'} ms)"); sw?.stop();
logger.info("${res.statusCode} ${req.method} ${req.uri} (${sw
?.elapsedMilliseconds ?? 'unknown'} ms)");
}
} }
}); });
} }
@ -670,38 +673,3 @@ class Angel extends AngelBase {
return new Angel.fromSecurityContext(serverContext); return new Angel.fromSecurityContext(serverContext);
} }
} }
/// Predetermines what needs to be injected for a handler to run.
InjectionRequest preInject(Function handler) {
var injection = new InjectionRequest();
ClosureMirror closureMirror = reflect(handler);
if (closureMirror.function.parameters.isEmpty) return injection;
// Load parameters
for (var parameter in closureMirror.function.parameters) {
var name = MirrorSystem.getName(parameter.simpleName);
var type = parameter.type.reflectedType;
if (!parameter.isNamed) {
if (parameter.isOptional) injection.optional.add(name);
if (type == RequestContext || type == ResponseContext) {
injection.required.add(type);
} else if (name == 'req') {
injection.required.add(RequestContext);
} else if (name == 'res') {
injection.required.add(ResponseContext);
} else if (type == dynamic) {
injection.required.add(name);
} else {
injection.required.add([name, type]);
}
} else {
injection.named[name] = type;
}
}
return injection;
}

View file

@ -1,5 +1,5 @@
name: angel_framework name: angel_framework
version: 1.1.0-alpha+3 version: 1.1.0-alpha+4
description: A high-powered HTTP server with DI, routing and more. description: A high-powered HTTP server with DI, routing and more.
author: Tobe O <thosakwe@gmail.com> author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/angel_framework homepage: https://github.com/angel-dart/angel_framework

View file

@ -6,7 +6,7 @@ import 'package:test/test.dart';
main() { main() {
test('preinjects functions', () async { test('preinjects functions', () async {
var app = new Angel() var app = new Angel()
..properties['foo'] = 'bar' ..configuration['foo'] = 'bar'
..get('/foo', echoAppFoo); ..get('/foo', echoAppFoo);
app.optimizeForProduction(force: true); app.optimizeForProduction(force: true);
print(app.preContained); print(app.preContained);

View file

@ -21,7 +21,7 @@ main() {
}); });
group('scoping', () { group('scoping', () {
var parent = new Angel()..properties['two'] = 2; var parent = new Angel()..configuration['two'] = 2;
var child = new Angel(); var child = new Angel();
parent.use('/child', child); parent.use('/child', child);
@ -66,10 +66,10 @@ main() {
test('plug-ins run on startup', () async { test('plug-ins run on startup', () async {
var app = new Angel(); var app = new Angel();
app.startupHooks.add((app) async { app.startupHooks.add((app) async {
app.properties['two'] = 2; app.configuration['two'] = 2;
}); });
await app.startServer(); await app.startServer();
expect(app.properties['two'], 2); expect(app.configuration['two'], 2);
await app.close(); await app.close();
}); });

View file

@ -21,9 +21,9 @@ main() {
}); });
test('can use app.properties like members', () { test('can use app.properties like members', () {
app.properties['hello'] = 'world'; app.configuration['hello'] = 'world';
app.properties['foo'] = () => 'bar'; app.configuration['foo'] = () => 'bar';
app.properties['Foo'] = new Foo('bar'); app.configuration['Foo'] = new Foo('bar');
expect(app.hello, equals('world')); expect(app.hello, equals('world'));
expect(app.foo(), equals('bar')); expect(app.foo(), equals('bar'));