Summary#
A namespace groups a file's types under a common name, so two parts of an app can each have an Order
without colliding. Write it once, at the top of the file, terminated by a semicolon:
namespace Shop.Catalog;It is optional. A file with no namespace declaration puts its types in the global namespace — which is
exactly what a single-file app wants, and what every example in this reference assumes.
Signature#
namespace Shop; // this file's types are Shop.*
entity Order { … } // → Shop.OrderDescription#
What it does to a name#
A type declared in a namespace gets that namespace as a prefix. namespace Shop; followed by entity Order
declares Shop.Order — that is the type's real, full name, the one you use to refer to it from elsewhere.
Inside the file that declares it, you just write Order.
Two forms — file-scoped and braced#
Osy# supports both C# forms:
namespace Shop; // file-scoped — opens the whole file (preferred)
namespace Shop { entity Order { … } } // braced — opens just its block
namespace Billing { entity Order { … } } // several braced namespaces may share one file- File-scoped (
namespace X;) opens the whole file: it must come before every other declaration, and a file may declare at most one. Prefer it for a file that is all one namespace. - Braced (
namespace X { … }) opens just its block, so a file may hold several and they may nest (namespace Shop { namespace Catalog { … } }puts a type inShop.Catalog). This is what lets C# code paste in verbatim.
A file uses one form or the other, never both — mixing a file-scoped namespace X; with a braced
namespace Y { … } in the same file is an error (as in C#).
How a name resolves#
When you write a bare name, it is looked for in this order — the first match wins, and no later step can make it ambiguous:
- The namespace you're in, then each enclosing one, working outward. Inside
namespace Shop.Catalog;that meansShop.Catalog, thenShop, then the global namespace. - The namespaces you imported with a
usingdeclaration. If two imports offer the same name, that is an error — qualify the reference to say which you mean. - The
Osyrincore, the platform's own namespace, always available without importing anything.
Because step 1 comes first, a type you declared always wins over one you imported. To reach the imported one anyway, write its full name.
The Osyrin namespace is the platform's#
Everything the platform ships lives under Osyrin. Its core types need no import. Its optional capabilities are
sub-namespaces — Osyrin.Memory, Osyrin.Storage, Osyrin.Ui, … — that you first depend on with a
use in your app { } manifest, then import with a using in each file that references their
names. You cannot declare a type in Osyrin yourself.
Reaching another namespace#
A sibling namespace's types are not visible bare — qualify them, exactly as in C#:
namespace Billing;
int Count() {
var orders = Shop.Order.Where(o => o.Code == "x").ToList(); // qualified
return orders.Count;
}Declaration names never contain a dot#
entity Shop.Order is an error. A dot in a declared name is how you'd spell a namespace, not how you declare
one — use namespace Shop; at the top of the file.
Examples#
// catalog.osy
namespace Shop;
entity Order {
[Required] string Code;
decimal Total;
}
int OpenOrders() {
// `Order` resolves to Shop.Order — the namespace this file is written in.
return Order.Where(o => o.Total > 0).ToList().Count;
}// billing.osy — a different namespace, so Shop.Order must be qualified.
namespace Billing;
entity Invoice {
Shop.Order Source;
decimal Amount;
}Step 3 applies in every position a type name can appear, including a property's type — a core type needs no import there either:
namespace Filing;
entity Attachment {
// `MarkdownDocument` is `Osyrin.MarkdownDocument`, found at step 3. Nothing is imported and nothing is qualified.
MarkdownDocument Body;
}See also#
- use —
usedeclares the capability dependency in the manifest;usingimports its names in a file. - type visibility (public / internal) —
publicandinternaldecide which of a namespace's types others can reach. - Osyrin.Ui (the UI kit) —
usingbrings a kit's public types into scope under their bare names.