Latest commit

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

SimpleServiceInterface

is a very simple implementation for connecting services via HTTP based JSON encoded API calls

IQueryable-Support

It supports service methods returning IQueryable<> as return type. The query on the IQueryable is serialized on the client, sent to the server and evaluated there. Only the result of the query is sent back to the client.

Demo

See source/Demo for an example of usage: Just start the SampleService.SelfhostedServer and connect to it with the SampleService.Client. Every method provided by the SampleService running on the server can be used by the client via JSON-encoded HTTP-calls.

What problem does this solve?

Let's say you have the following interface:

// your service interfacepublicinterfaceISampleService{IQueryable<SampleClass>GetAll();}// your data class which contains some sample data fieldspublicclassSampleClass{publiclongId{get;set;}publicGuidId2{get;set;}privatestringText{get;set;}publicDateTimeDate{get;set;}}

You want to provide this interface as a service via HTTP, for example for your microservices. Microservice B consumes data from Microservice A, which is the data store for SampleClass. But the way Microservice A needs data depends on the actual case. Sometimes it needs to filter only by Id, sometimes it also needs to use the Text property or the Date property also. Other times, you only need a field or two and not all the data for each entry. Or even more, Microservice B sometimes needs a grouped or aggregated (for example min/max) result from Microservice A.

The most naive way would be to just send all the data as a list to the client and the client then can do all the operations it needs to. But that isn't efficient and leads to performance issues, both on serialization/deserialization, CPU time and memory consumption on filtering on the client and also network bandwith.

In a usual webservice, you would define different methods for different purposes or sophisticated query and result objects. But that can lead to regular additions or changes to the interface, which can (at least temporarily) break your application.

Another option is OData, but it comes with the handicap of not being fully LINQ compatible, so you may have to rewrite your queries. (To be fair: If you want to exchange data between different platforms and programming languages, OData is still the best choice for you.)

But in the end, all you want to do is write C# code in your Microservice B like this:

sampleService.GetAll().Where(x =>x.Id<3).Select(x =>newTuple<long,DateTime>(x.Id,x.Date)).OrderByDescending(i =>i.Item1).ToList();

And you don't want to worry about CPU, RAM or network usage and you don't want to change the interface with every use case. You just want to query your data as it were local. That also makes testing a lot easier.

And this is exactly what SimpleServiceInterface can do for you.

Just

  • create a common interface for your service
  • write an implementation for the service
  • host the service implementation either as self-hosted service (SimpleServiceServerOwin) or in IIS (SimpleServiceServerSystemWebHttpHandler)
  • use the SimpleServiceClient on the client side to use the service

About

A very simple implementation for connecting services via HTTP based JSON encoded API calls

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

SimpleServiceInterface

is a very simple implementation for connecting services via HTTP based JSON encoded API calls

IQueryable-Support

It supports service methods returning IQueryable<> as return type. The query on the IQueryable is serialized on the client, sent to the server and evaluated there. Only the result of the query is sent back to the client.

Demo

See source/Demo for an example of usage: Just start the SampleService.SelfhostedServer and connect to it with the SampleService.Client. Every method provided by the SampleService running on the server can be used by the client via JSON-encoded HTTP-calls.

What problem does this solve?

Let's say you have the following interface:

// your service interfacepublicinterfaceISampleService{IQueryable<SampleClass>GetAll();}// your data class which contains some sample data fieldspublicclassSampleClass{publiclongId{get;set;}publicGuidId2{get;set;}privatestringText{get;set;}publicDateTimeDate{get;set;}}

You want to provide this interface as a service via HTTP, for example for your microservices. Microservice B consumes data from Microservice A, which is the data store for SampleClass. But the way Microservice A needs data depends on the actual case. Sometimes it needs to filter only by Id, sometimes it also needs to use the Text property or the Date property also. Other times, you only need a field or two and not all the data for each entry. Or even more, Microservice B sometimes needs a grouped or aggregated (for example min/max) result from Microservice A.

The most naive way would be to just send all the data as a list to the client and the client then can do all the operations it needs to. But that isn't efficient and leads to performance issues, both on serialization/deserialization, CPU time and memory consumption on filtering on the client and also network bandwith.

In a usual webservice, you would define different methods for different purposes or sophisticated query and result objects. But that can lead to regular additions or changes to the interface, which can (at least temporarily) break your application.

Another option is OData, but it comes with the handicap of not being fully LINQ compatible, so you may have to rewrite your queries. (To be fair: If you want to exchange data between different platforms and programming languages, OData is still the best choice for you.)

But in the end, all you want to do is write C# code in your Microservice B like this:

sampleService.GetAll().Where(x =>x.Id<3).Select(x =>newTuple<long,DateTime>(x.Id,x.Date)).OrderByDescending(i =>i.Item1).ToList();

And you don't want to worry about CPU, RAM or network usage and you don't want to change the interface with every use case. You just want to query your data as it were local. That also makes testing a lot easier.

And this is exactly what SimpleServiceInterface can do for you.

Just

  • create a common interface for your service
  • write an implementation for the service
  • host the service implementation either as self-hosted service (SimpleServiceServerOwin) or in IIS (SimpleServiceServerSystemWebHttpHandler)
  • use the SimpleServiceClient on the client side to use the service

About

A very simple implementation for connecting services via HTTP based JSON encoded API calls

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

SimpleServiceInterface

is a very simple implementation for connecting services via HTTP based JSON encoded API calls

IQueryable-Support

It supports service methods returning IQueryable<> as return type. The query on the IQueryable is serialized on the client, sent to the server and evaluated there. Only the result of the query is sent back to the client.

Demo

See source/Demo for an example of usage: Just start the SampleService.SelfhostedServer and connect to it with the SampleService.Client. Every method provided by the SampleService running on the server can be used by the client via JSON-encoded HTTP-calls.

What problem does this solve?

Let's say you have the following interface:

// your service interfacepublicinterfaceISampleService{IQueryable<SampleClass>GetAll();}// your data class which contains some sample data fieldspublicclassSampleClass{publiclongId{get;set;}publicGuidId2{get;set;}privatestringText{get;set;}publicDateTimeDate{get;set;}}

You want to provide this interface as a service via HTTP, for example for your microservices. Microservice B consumes data from Microservice A, which is the data store for SampleClass. But the way Microservice A needs data depends on the actual case. Sometimes it needs to filter only by Id, sometimes it also needs to use the Text property or the Date property also. Other times, you only need a field or two and not all the data for each entry. Or even more, Microservice B sometimes needs a grouped or aggregated (for example min/max) result from Microservice A.

The most naive way would be to just send all the data as a list to the client and the client then can do all the operations it needs to. But that isn't efficient and leads to performance issues, both on serialization/deserialization, CPU time and memory consumption on filtering on the client and also network bandwith.

In a usual webservice, you would define different methods for different purposes or sophisticated query and result objects. But that can lead to regular additions or changes to the interface, which can (at least temporarily) break your application.

Another option is OData, but it comes with the handicap of not being fully LINQ compatible, so you may have to rewrite your queries. (To be fair: If you want to exchange data between different platforms and programming languages, OData is still the best choice for you.)

But in the end, all you want to do is write C# code in your Microservice B like this:

sampleService.GetAll().Where(x =>x.Id<3).Select(x =>newTuple<long,DateTime>(x.Id,x.Date)).OrderByDescending(i =>i.Item1).ToList();

And you don't want to worry about CPU, RAM or network usage and you don't want to change the interface with every use case. You just want to query your data as it were local. That also makes testing a lot easier.

And this is exactly what SimpleServiceInterface can do for you.

Just

  • create a common interface for your service
  • write an implementation for the service
  • host the service implementation either as self-hosted service (SimpleServiceServerOwin) or in IIS (SimpleServiceServerSystemWebHttpHandler)
  • use the SimpleServiceClient on the client side to use the service

About

A very simple implementation for connecting services via HTTP based JSON encoded API calls

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

SimpleServiceInterface

is a very simple implementation for connecting services via HTTP based JSON encoded API calls

IQueryable-Support

It supports service methods returning IQueryable<> as return type. The query on the IQueryable is serialized on the client, sent to the server and evaluated there. Only the result of the query is sent back to the client.

Demo

See source/Demo for an example of usage: Just start the SampleService.SelfhostedServer and connect to it with the SampleService.Client. Every method provided by the SampleService running on the server can be used by the client via JSON-encoded HTTP-calls.

What problem does this solve?

Let's say you have the following interface:

// your service interfacepublicinterfaceISampleService{IQueryable<SampleClass>GetAll();}// your data class which contains some sample data fieldspublicclassSampleClass{publiclongId{get;set;}publicGuidId2{get;set;}privatestringText{get;set;}publicDateTimeDate{get;set;}}

You want to provide this interface as a service via HTTP, for example for your microservices. Microservice B consumes data from Microservice A, which is the data store for SampleClass. But the way Microservice A needs data depends on the actual case. Sometimes it needs to filter only by Id, sometimes it also needs to use the Text property or the Date property also. Other times, you only need a field or two and not all the data for each entry. Or even more, Microservice B sometimes needs a grouped or aggregated (for example min/max) result from Microservice A.

The most naive way would be to just send all the data as a list to the client and the client then can do all the operations it needs to. But that isn't efficient and leads to performance issues, both on serialization/deserialization, CPU time and memory consumption on filtering on the client and also network bandwith.

In a usual webservice, you would define different methods for different purposes or sophisticated query and result objects. But that can lead to regular additions or changes to the interface, which can (at least temporarily) break your application.

Another option is OData, but it comes with the handicap of not being fully LINQ compatible, so you may have to rewrite your queries. (To be fair: If you want to exchange data between different platforms and programming languages, OData is still the best choice for you.)

But in the end, all you want to do is write C# code in your Microservice B like this:

sampleService.GetAll().Where(x =>x.Id<3).Select(x =>newTuple<long,DateTime>(x.Id,x.Date)).OrderByDescending(i =>i.Item1).ToList();

And you don't want to worry about CPU, RAM or network usage and you don't want to change the interface with every use case. You just want to query your data as it were local. That also makes testing a lot easier.

And this is exactly what SimpleServiceInterface can do for you.

Just

  • create a common interface for your service
  • write an implementation for the service
  • host the service implementation either as self-hosted service (SimpleServiceServerOwin) or in IIS (SimpleServiceServerSystemWebHttpHandler)
  • use the SimpleServiceClient on the client side to use the service

About

A very simple implementation for connecting services via HTTP based JSON encoded API calls

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

SimpleServiceInterface

is a very simple implementation for connecting services via HTTP based JSON encoded API calls

IQueryable-Support

It supports service methods returning IQueryable<> as return type. The query on the IQueryable is serialized on the client, sent to the server and evaluated there. Only the result of the query is sent back to the client.

Demo

See source/Demo for an example of usage: Just start the SampleService.SelfhostedServer and connect to it with the SampleService.Client. Every method provided by the SampleService running on the server can be used by the client via JSON-encoded HTTP-calls.

What problem does this solve?

Let's say you have the following interface:

// your service interfacepublicinterfaceISampleService{IQueryable<SampleClass>GetAll();}// your data class which contains some sample data fieldspublicclassSampleClass{publiclongId{get;set;}publicGuidId2{get;set;}privatestringText{get;set;}publicDateTimeDate{get;set;}}

You want to provide this interface as a service via HTTP, for example for your microservices. Microservice B consumes data from Microservice A, which is the data store for SampleClass. But the way Microservice A needs data depends on the actual case. Sometimes it needs to filter only by Id, sometimes it also needs to use the Text property or the Date property also. Other times, you only need a field or two and not all the data for each entry. Or even more, Microservice B sometimes needs a grouped or aggregated (for example min/max) result from Microservice A.

The most naive way would be to just send all the data as a list to the client and the client then can do all the operations it needs to. But that isn't efficient and leads to performance issues, both on serialization/deserialization, CPU time and memory consumption on filtering on the client and also network bandwith.

In a usual webservice, you would define different methods for different purposes or sophisticated query and result objects. But that can lead to regular additions or changes to the interface, which can (at least temporarily) break your application.

Another option is OData, but it comes with the handicap of not being fully LINQ compatible, so you may have to rewrite your queries. (To be fair: If you want to exchange data between different platforms and programming languages, OData is still the best choice for you.)

But in the end, all you want to do is write C# code in your Microservice B like this:

sampleService.GetAll().Where(x =>x.Id<3).Select(x =>newTuple<long,DateTime>(x.Id,x.Date)).OrderByDescending(i =>i.Item1).ToList();

And you don't want to worry about CPU, RAM or network usage and you don't want to change the interface with every use case. You just want to query your data as it were local. That also makes testing a lot easier.

And this is exactly what SimpleServiceInterface can do for you.

Just

  • create a common interface for your service
  • write an implementation for the service
  • host the service implementation either as self-hosted service (SimpleServiceServerOwin) or in IIS (SimpleServiceServerSystemWebHttpHandler)
  • use the SimpleServiceClient on the client side to use the service

About

A very simple implementation for connecting services via HTTP based JSON encoded API calls

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

SimpleServiceInterface

is a very simple implementation for connecting services via HTTP based JSON encoded API calls

IQueryable-Support

It supports service methods returning IQueryable<> as return type. The query on the IQueryable is serialized on the client, sent to the server and evaluated there. Only the result of the query is sent back to the client.

Demo

See source/Demo for an example of usage: Just start the SampleService.SelfhostedServer and connect to it with the SampleService.Client. Every method provided by the SampleService running on the server can be used by the client via JSON-encoded HTTP-calls.

What problem does this solve?

Let's say you have the following interface:

// your service interfacepublicinterfaceISampleService{IQueryable<SampleClass>GetAll();}// your data class which contains some sample data fieldspublicclassSampleClass{publiclongId{get;set;}publicGuidId2{get;set;}privatestringText{get;set;}publicDateTimeDate{get;set;}}

You want to provide this interface as a service via HTTP, for example for your microservices. Microservice B consumes data from Microservice A, which is the data store for SampleClass. But the way Microservice A needs data depends on the actual case. Sometimes it needs to filter only by Id, sometimes it also needs to use the Text property or the Date property also. Other times, you only need a field or two and not all the data for each entry. Or even more, Microservice B sometimes needs a grouped or aggregated (for example min/max) result from Microservice A.

The most naive way would be to just send all the data as a list to the client and the client then can do all the operations it needs to. But that isn't efficient and leads to performance issues, both on serialization/deserialization, CPU time and memory consumption on filtering on the client and also network bandwith.

In a usual webservice, you would define different methods for different purposes or sophisticated query and result objects. But that can lead to regular additions or changes to the interface, which can (at least temporarily) break your application.

Another option is OData, but it comes with the handicap of not being fully LINQ compatible, so you may have to rewrite your queries. (To be fair: If you want to exchange data between different platforms and programming languages, OData is still the best choice for you.)

But in the end, all you want to do is write C# code in your Microservice B like this:

sampleService.GetAll().Where(x =>x.Id<3).Select(x =>newTuple<long,DateTime>(x.Id,x.Date)).OrderByDescending(i =>i.Item1).ToList();

And you don't want to worry about CPU, RAM or network usage and you don't want to change the interface with every use case. You just want to query your data as it were local. That also makes testing a lot easier.

And this is exactly what SimpleServiceInterface can do for you.

Just

  • create a common interface for your service
  • write an implementation for the service
  • host the service implementation either as self-hosted service (SimpleServiceServerOwin) or in IIS (SimpleServiceServerSystemWebHttpHandler)
  • use the SimpleServiceClient on the client side to use the service

About

A very simple implementation for connecting services via HTTP based JSON encoded API calls

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

SimpleServiceInterface

is a very simple implementation for connecting services via HTTP based JSON encoded API calls

IQueryable-Support

It supports service methods returning IQueryable<> as return type. The query on the IQueryable is serialized on the client, sent to the server and evaluated there. Only the result of the query is sent back to the client.

Demo

See source/Demo for an example of usage: Just start the SampleService.SelfhostedServer and connect to it with the SampleService.Client. Every method provided by the SampleService running on the server can be used by the client via JSON-encoded HTTP-calls.

What problem does this solve?

Let's say you have the following interface:

// your service interfacepublicinterfaceISampleService{IQueryable<SampleClass>GetAll();}// your data class which contains some sample data fieldspublicclassSampleClass{publiclongId{get;set;}publicGuidId2{get;set;}privatestringText{get;set;}publicDateTimeDate{get;set;}}

You want to provide this interface as a service via HTTP, for example for your microservices. Microservice B consumes data from Microservice A, which is the data store for SampleClass. But the way Microservice A needs data depends on the actual case. Sometimes it needs to filter only by Id, sometimes it also needs to use the Text property or the Date property also. Other times, you only need a field or two and not all the data for each entry. Or even more, Microservice B sometimes needs a grouped or aggregated (for example min/max) result from Microservice A.

The most naive way would be to just send all the data as a list to the client and the client then can do all the operations it needs to. But that isn't efficient and leads to performance issues, both on serialization/deserialization, CPU time and memory consumption on filtering on the client and also network bandwith.

In a usual webservice, you would define different methods for different purposes or sophisticated query and result objects. But that can lead to regular additions or changes to the interface, which can (at least temporarily) break your application.

Another option is OData, but it comes with the handicap of not being fully LINQ compatible, so you may have to rewrite your queries. (To be fair: If you want to exchange data between different platforms and programming languages, OData is still the best choice for you.)

But in the end, all you want to do is write C# code in your Microservice B like this:

sampleService.GetAll().Where(x =>x.Id<3).Select(x =>newTuple<long,DateTime>(x.Id,x.Date)).OrderByDescending(i =>i.Item1).ToList();

And you don't want to worry about CPU, RAM or network usage and you don't want to change the interface with every use case. You just want to query your data as it were local. That also makes testing a lot easier.

And this is exactly what SimpleServiceInterface can do for you.

Just

  • create a common interface for your service
  • write an implementation for the service
  • host the service implementation either as self-hosted service (SimpleServiceServerOwin) or in IIS (SimpleServiceServerSystemWebHttpHandler)
  • use the SimpleServiceClient on the client side to use the service

About

A very simple implementation for connecting services via HTTP based JSON encoded API calls

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

29 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

SimpleServiceInterface

is a very simple implementation for connecting services via HTTP based JSON encoded API calls

IQueryable-Support

It supports service methods returning IQueryable<> as return type. The query on the IQueryable is serialized on the client, sent to the server and evaluated there. Only the result of the query is sent back to the client.

Demo

See source/Demo for an example of usage: Just start the SampleService.SelfhostedServer and connect to it with the SampleService.Client. Every method provided by the SampleService running on the server can be used by the client via JSON-encoded HTTP-calls.

What problem does this solve?

Let's say you have the following interface:

// your service interfacepublicinterfaceISampleService{IQueryable<SampleClass>GetAll();}// your data class which contains some sample data fieldspublicclassSampleClass{publiclongId{get;set;}publicGuidId2{get;set;}privatestringText{get;set;}publicDateTimeDate{get;set;}}

You want to provide this interface as a service via HTTP, for example for your microservices. Microservice B consumes data from Microservice A, which is the data store for SampleClass. But the way Microservice A needs data depends on the actual case. Sometimes it needs to filter only by Id, sometimes it also needs to use the Text property or the Date property also. Other times, you only need a field or two and not all the data for each entry. Or even more, Microservice B sometimes needs a grouped or aggregated (for example min/max) result from Microservice A.

The most naive way would be to just send all the data as a list to the client and the client then can do all the operations it needs to. But that isn't efficient and leads to performance issues, both on serialization/deserialization, CPU time and memory consumption on filtering on the client and also network bandwith.

In a usual webservice, you would define different methods for different purposes or sophisticated query and result objects. But that can lead to regular additions or changes to the interface, which can (at least temporarily) break your application.

Another option is OData, but it comes with the handicap of not being fully LINQ compatible, so you may have to rewrite your queries. (To be fair: If you want to exchange data between different platforms and programming languages, OData is still the best choice for you.)

But in the end, all you want to do is write C# code in your Microservice B like this:

sampleService.GetAll().Where(x =>x.Id<3).Select(x =>newTuple<long,DateTime>(x.Id,x.Date)).OrderByDescending(i =>i.Item1).ToList();

And you don't want to worry about CPU, RAM or network usage and you don't want to change the interface with every use case. You just want to query your data as it were local. That also makes testing a lot easier.

And this is exactly what SimpleServiceInterface can do for you.

Just

  • create a common interface for your service
  • write an implementation for the service
  • host the service implementation either as self-hosted service (SimpleServiceServerOwin) or in IIS (SimpleServiceServerSystemWebHttpHandler)
  • use the SimpleServiceClient on the client side to use the service

About

A very simple implementation for connecting services via HTTP based JSON encoded API calls

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages