ssannandeji / zenject-2019 Goto Github PK
View Code? Open in Web Editor NEWThis project forked from sebas77/-obsolete-lightweight-ioc-container-for-unity3d
Dependency Injection Framework for Unity3D
License: MIT License
This project forked from sebas77/-obsolete-lightweight-ioc-container-for-unity3d
Dependency Injection Framework for Unity3D
License: MIT License
When registering a variable whose declared type is object
using DiContainer.BindAllInterfacesToInstance<TConcrete>(TConcrete value)
, the typeof(TConcrete)
statement is evaluating to Object
, and not the type of the value
argument. This results in the interfaces of value
not being found.
Calling BindAllInterfacesToInstance(myInstance.GetType(), myInstance)
does work however.
Possibly DiContainer.BindAllInterfacesToInstance<TConcrete>(TConcrete value)
does not need to be generic? This would fix the issue.
Given the following:
class Test8
{
public int Val1;
public Test8(
[InjectOptional]
int val1 = 6)
{
Val1 = val1;
}
}
And the binding:
Container.Bind<Test8>().ToSingle();
The value of Container.Resolve<Test8>().Val1
should be 6, however it gets set to zero.
I have this issue after update from asset store. Removing of Func<T1, T2, T3, T4, T5, TResult>
from Func
file in Internal
folder solves the problem.
Is it possible to make this behavior configurable?
GetInjectConstructor retrieves at least 2 constructors whatever the type:
Void .ctor()
with Attributes = FamANDAssem | Family | HideBySig | SpecialName | RTSpecialName
Void .ctor(UIntPtr)
with Attributes = Private | Family | HideBySig | SpecialName | RTSpecialName
As none is marked with [Inject]
GetInjectConstructor
always returns NULL
If we bypass test
if (constructors.HasMoreThan(1))
{
// This will return null if there is more than one constructor and none are marked with the [Inject] attribute
return (from c in constructors where c.HasAttribute<InjectAttribute>() select c).SingleOrDefault();
}
everything works fine as first one is used as expected.
Anyone an idea regarding this?
For some reason zenject does neither call the constructor nor the init()
method of this Dummy class
public class DummyClass {
[Inject]
RoomController controller;
public DummyClass() {
Debug.Log("dummy constructor called");
}
[PostInject]
void init() {
Debug.Log("Dummyclass init called");
}
}
This is the binding
public class GameInstaller : MonoInstaller {
public override void InstallBindings() {
Container.Bind<DummyClass>().ToSingle();
}
}
Am I doing something wrong here?
I am creating a small MVC library for Unity. I would like the user to be able to have its prefabs in some folder, tell the framework the path to each prefab and the type of the controller attach to that prefab, so the framework is able to switch between views. Using Zenject I have something like this:
container.Bind<SomeController>().ToPrefab("path/in/Resources");
app.RegisterRoute<SomeController>("path/in/Resources");
public static void ToPrefab<T>(this BinderGeneric<T> binder, String prefabLocation) where T : UnityEngine.Object {
binder.ToMethod((ctx) => {
var obj = UnityEngine.Object.Instantiate(Resources.Load(prefabLocation)) as GameObject;
return obj.GetComponent<T>();
});
}
Type type = views[url];
current = (MonoBehaviour)container.Resolve(type);
It very nice that at least it instantiates the correct object, but the Component returned during the binder.ToMethod
lambda is not getting any [PostInject]
methods executed. I can solve this two ways but I don't know how:
binder.ToMethod
lamda to get injection into the resulting object;container.Resolve
is called on the GoTo
procedure?I have code
var c = _container.CreateSubContainer();
c.Bind<int>().ToInstance(x);
c.Resolve<IPoint>();
and I get exeption "ZenjectResolveException: Unable to resolve type 'int' while building object with type 'Point'. "
main container don't get sub-container bindings?
Are dependencies injected into the object that is created while using ToSingleInstance() kind of injection?
Having
Container.Bind<MyClass>().ToSingleInstance(new MyClass(myparams));
Will MyClass instance get it's field dependencies?
In some cases (MonoBehaviours and circular dependencies) we are not able to use constructor injection and therefore must use either property or field injection. What might be nice as another alternative for these cases is to be able to add parameters to the methods that are marked as [PostInject] and have Zenject automatically resolve those dependencies.
TransientMockProvider seems to be broken due to Fasterflect missing dependency Method
:
public override object GetInstance(Type contractType, InjectContext context)
{
object instance;
if (!_instances.TryGetValue(contractType, out instance))
{
instance = typeof(Mock).Method(new[] { contractType }, "Of", Flags.StaticAnyVisibility).Invoke(null, null);
_instances.Add(contractType, instance);
}
return instance;
}
This would be especially useful with tests, where you often want to use the same installers that are used in production, except replace a few specific bindings with their test versions.
So compilation of Zenject to dll is broken.
There are some free CI tools to prevent that issues, however I have not any experience with them :)
Hi,
just imported ZenJect into my project and when I build my game for WP8 I get the following error:
Error building Player: Exception: Error: method `System.Void System.Array::SetValue(System.Object,System.Int64)` doesn't exist in target framework. It is referenced from Fasterflect.dll at System.Object Fasterflect.ArrayExtensions::SetElement(System.Object,System.Int64,System.Object).
Error: method `System.Object System.Array::GetValue(System.Int64)` doesn't exist in target framework. It is referenced from Fasterflect.dll at System.Object Fasterflect.ArrayExtensions::GetElement(System.Object,System.Int64).
Greetings Christian
Hi.
Could you please add more information on how to properly instantiate new objects dynamically.
I mean - Instantiating a new Prefab with my object.
GameObject.Instnatiate does not inject dependencies, of course.
I looked into documentation and there seem to be old GameObjectInstantiator, that was removed, and a new IInstantiator interface.
Which implementation of IInstantiator should I use to create a new Prefab in my custom class that is not a MonoInstaller instance?
What I want is to create a new prefab that has some script attached to it, and have all dependencies provided for that script.
How to know which commit is which release?
Usually, people use tags for that purpose. It would be nice if you could add those tags, as for now there is only 1 tag called "v1.18" while the documentation mentions v3.2 already.
In InstallBindings()
Container.Bind<int>().ToInstance(42);
MonoBehaviour:
public class Question : MonoBehaviour {
[Inject]
protected int Answer = 3;
}
When that MonoBehaviour is attached to an inactive GameObject and I run the scene in the editor, the field value stays 3. When the GameObject is active, the field value is set to 42.
I'm guessing this is due to the way Unity is reluctant to let you find GameObjects that are inactive.
I would expect the field value to be set to 42 whether or not the GameObject was active.
Hello,
I'm trying to use Zenject in a project with multiple scenes and there seems to be no injection for the MonoBehaviours that are loaded from the new scene.
My project baically is:
I tried to setup the bindings in the main installer and in the delegate for LoadLevel. But nothing gets injected.
Is there any way to get this working, or do I have to change my project structure?
Currently there is only a ToSingleMethod
but I specifically need the dependency to be transient. Can this method be added to Zenject? I am trying to do the same as yesterday but now by passing types as parameters
public static void ToPrefab(this BinderUntyped binder, String prefabLocation, Type type)
{
//NEED TRANSIENT VERSION
binder.ToSingleMethod((ctx) => {
var obj = Resources.Load(prefabLocation) as GameObject;
return ctx.Container.InstantiatePrefabForComponent(type, obj) as MonoBehaviour;
});
}
lazy instantiation of object would allow creation of objects only if they are injected into other one.
Currently, I can see Zenject only support Windows 8.0 and Windows Phone 8.0 SDK.
Have you ever planned to support Universal Apps for Windows ? Indeed, there is some bugs when it compiles a build (Tuple namespace, not existing assembly).
Thanks.
Hey,
I downloaded the package from the asset store and I am trying to follow the steps in the Hello-World-Tutorial.
However: The right click menu entry for Zenject is not showing. What am I doing wrong?
I found some entries in the Component Menu, so I will try to work around this somehow.
Just thought I should report this.
Thanks, Ruben
When importing the package from Unity3D, the user has to deselect some files which he doesn't need.
There are details I want to point:
I always find myself disabling elements that i need disabled when they start so the injection works properly.
Is there any way to be able to inject dependencies into disabled objects?
How do I Inject Bindings into a scene that is loaded additive ?
I have the my main StateMachine for the Game ( that handles all state and Scene switches )
Its created by my installer in the application Warmup like this :
Container.Bind<GameStateMachine>().ToSingleFromPrefab<GameStateMachine>(_gameStateMachinePrefab);
To keep loading times short my warm-up scene is nearly empty ( Installer + Loading Grafics )
From this point I load the needed scene async and additive ( while I can show loading animations etc. )
How do I Inject my main stateMachine ( or any other binding ) to this additive loaded scenes ?
I tried:
[PostInject]
public void Init(GameStateMachine gameStateMachine){
this.gameStateMachine = gameStateMachine;
}
but it doesn't get called at all.
So what is the recommended approach for this ? Thanks for your help.
Friedrich Wessel
Repro steps:
Open a scene decorator scene that opens another scene decorator scene
Hit CTRL+V
Observe that this doesn't work properly
Hi there!
The following two source files seem to address a different global installer asset:
In my project I just assumed the name 'ZenjectGlobalInstallers' by renaming the generated asset.
While I was following the readme and tried to create a custom factory with manual instantiation of objects I found out that Instantiate method is not there.
Checked file history. It seems that it is now called InstantiateInternal and it is not public. There is InstantiateExplicit method but there are no examples on how to use it (using it like described in readme doesn't work).
EDIT: This seems to only be a problem with the Asset Store version.
When opening the Asteroids-scene and running it the asteroid-tag on the Asteroid-prefab disappears so on consecutive runs the following Assert fails in ShipStateMoving.cs:
public override void OnTriggerEnter(Collider other)
{
Assert.That(other.tag == "asteroid");
_ship.ChangeState(ShipStates.Dead, _ship);
}
Reopening the project resets the tag back until you run the scene once again. Unity seems to remove the tag because the tag does not exist in the projects TagManager; which isn't supplied by Zenject since it's not a complete project, only a scene.
I'm thinking that tags shouldn't be used in the sample or the sample should be made into a complete Unity project. Other suggestions?
Hey there
Just a heads up, Unity 5 has added a new attribute RuntimeInitializeOnLoadMethodAttribute
which allows you to have a main entry point into the game.
Possibly a good place to initialize the global composition root in Unity 5?
I am trying to figure out how I would inject two specific instances into a new instance of my SpecialPurchaseMethodProcessor
class along with regular injected arguments.
public class DefaultPurchaseMethodProcessorFactory : IPurchaseMethodProcessorFactory {
...
private DiContainer _container;
private Dictionary<Type, Func<IPurchaseMethodProcessor>> _creators;
public void Bind<TPurchaseMethod, TPurchaseMethodProcessor>()
where TPurchaseMethod : IPurchaseMethod
where TPurchaseMethodProcessor : IPurchaseMethodProcessor
{
_creators[typeof(TPurchaseMethod)] = () => _container.Resolve<TPurchaseMethodProcessor>();
}
public IPurchaseMethodProcessor CreateProcessor(IPurchasableItem item, IPurchaseMethod method) {
var creator = _creators[item.GetType()];
return creator();
}
}
public sealed class SpecialPurchaseMethodProcessor : IPurchaseMethodProcessor {
public SpecialPurchaseMethodProcessor(
// Specific item for which to create processor for:
IPurchasableItem item,
IPurchaseMethod method,
// Injected types as normal:
IVirtualCurrencyManager currencies
) {
...
}
...
}
So this would be consumed as follows:
var processor = factory.CreateProcessor(jellyBeansItem, virtualCurrencyPurchaseMethod);
if (processor.CanPurchase)
processor.InitiatePurchase();
Does Zenject provide a way to solve this problem? or am I just going about this in the wrong way?
I've bumped into this a couple of times and feel that it would be quite nice if Zenject was able to determine whether a constructor dependency was optional when a default parameter value is present:
public class Foo {
...
public Foo(IBar bar, IBaz baz = null) {
...
}
}
Rather than just throwing the following exception:
ZenjectResolveException: Unable to resolve type 'IBaz' while building object with type 'Foo'.
Ideally I would prefer to avoid annotating these parameters with an attribute since this can already be deduced using reflection like the following:
if (injectedParameterValue == null) {
bool isOptionalParameter = parameterInfo.IsOptional || ReflectionUtility.HasZenjectOptionalAttribute(parameterInfo);
if (!isOptionalParameter)
throw new ZenjectResolveException();
// `Type.Missing` is suggested in MSDN (probably to avoid boxing on value types):
// https://msdn.microsoft.com/en-us/library/system.type.missing(v=vs.110).aspx
injectedParameterValue = Type.Missing;
}
Is this something that can be added?
Many thanks!
See here for a description of the problem
I want to avoid other programmers to create new instances of my class by using the new
word.
Therefore I create factory classes inside all of my entity classes and provide a private standard constructor private Entity(){}
only to avoid instantiation via new
but force them to use the factory instead.
public class Furniture {
FurnitureView view;
Player player;
//enforces that nobody can create an instance via "new" from outside
private Furniture() {}
//Internal class, inherite from Factory<T,U> to enforce Create method to expect T,U parameters
public class Factory : Factory<FurnitureView, Player, Furniture> {
}
}
Now Zenject can't inject the view and player
My workaround is to just override create
public class Factory : Factory<FurnitureView, Player, Furniture> {
public override Furniture Create(FurnitureView view, Player owner) {
var res = base.Create(view, owner);
res.View = view;
res.Player = owner;
return res;
}
}
But then Zenject will recognize the passed parameters as unnecessary
Error 1 ZenjectResolveException: Passed unnecessary parameters when injecting into type 'Furniture'.
So how can I solve this without creating a public constructor public Furniture(FurnitureView view, Player owner){...}
that serves for Zenject's constructor injection?
Currently, we have two factory implementations: IFactory/Factory and FactoryTyped. FactoryTyped is the preferable approach, since it is strongly typed (unlike IFactory) and is also automatically validated (an example can be found here). It should therefore probably become the standard factory class so we may want to rename it to just Factory during the next breaking version update
Both approaches have the issue that null arguments result in an exception being thrown. This is because both approaches rely on the type information to figure out which field/parameter to inject into. This is problematic when you actually do want to inject a null value so we need to address that. It is also an issue when you want to inject multiple instances of the same type into a class via factory arguments.
So I think we may want to use the ordering information provided to the factories to handle these cases.
We get following error when validating the szene :
ZenjectResolveException: Expected contract type 'IControllerStrategy' to be non-abstract
With following code:
Container.Bind<ControllerStrategyFactory>().ToSingle();
public class ControllerStrategyFactory : Factory<StrategyId, IModel_Writeable, IControllerStrategy>
{
public override IControllerStrategy Create (StrategyId strategyId, IModel_Writeable model) {
What do we need to change ?
Thanks in advance
Best regard
Marcel Schmidt
Tried current version of Zenject from the Asset Store (2.4 (Apr 21, 2015)). It compiles fine in Unity itself, but fails to compile in MonoDevelop.
CS0241 - Default parameter specifiers are not permitted... etc. This error is obvious: MonoDevelop is defaulted to Mono/.Net 3.5, where they are just not implemented.
There are two possibilities to overcome the error:
The first one works like a charm, of course. And, in my opinion, it is currently necessary not to use default parameters in the assets at all, as long as MonoDevelop is defaulted to 3.5. So, you probably need to fix this...
But there's more: when I try the second workaround the CS0241 error is gone, but I get a bunch of CS0104 ambiguous references between System and ModestTree Func and Tuple. Here I'm not really sure how to deal with this, since C# and Mono/.NET don't provide version defines, which are desired for such situation. Possibly a good idea is to create a custom define, so we could switch between ModestTree to System versions manually, when necessary.
Looking at the MonoInstaller
class I have not been able to deduce whether this is already possible.
Essentially this is the sort of thing I was looking for:
public sealed class Installer : MonoInstaller, IInitializable {
public override void InstallBindings() { ... }
void IInitializable.Initialize() {
// Do some initial setup whilst taking advantage of all available bindings...
}
}
Cheers!
Error
Unable to locate GraphViz. Please select the graphviz 'dot.exe' file which can be found at [GraphVizInstallDirectory]/bin/dot.exe. If you do not have GraphViz you can download it at http://www.graphviz.org
Context
I was testing out the Object Graph Output feature of Zenject. The ObjectGraph.dot file is still generated correctly and it is still possible to manually generate the image from the dot file with the following terminal command:
dot -T png ObjectGraph.dot -o ObjectGraph.png
Proposition / Solution
I think it would be interesting to have some compile time conditions to change the default behaviour seen here to something more multiplatform in the future:
https://github.com/modesttree/Zenject/blob/master/UnityProject/Assets/Zenject/Main/Editor/ZenEditorUtil.cs#L179
Something along the lines of (or different/cleaner solutions, like condition on the path EditorPrefs key?):
if UNITY_EDITOR_WIN
var dotExecPath = EditorPrefs.GetString("Zenject.GraphVizDotOSXPath", "");
elif UNITY_EDITOR_OSX
var dotExecPath = EditorPrefs.GetString("Zenject.GraphVizDotExePath", "");
endif
The main problem would be to detect where graphviz is installed I guess? I installed it using Homebrew (brew install graphviz) and here is where the file resides for me:
โ UnityProject git:(master) โ which dot
/usr/local/bin/dot
The OpenFilePanel does not seem to allow the user to navigate to that path on my system, so manual executable path selection would not be possible on OSX but I think it would also not be necessary since according to this article, the default install path would be this in most cases:
Default Path: Linux / Mac OSX
/usr/local/bin/dot or /usr/bin/dot
This is obviously not a major issue in my opinion and this bug report would allow any OSX user to generate the output image using the command specified up above. Let me know if you have any questions for testing a fix for this on OSX.
Is it possible to get a singleton instance with the help of some function?
I have different implementations for keyboard input and I have a binding like this
public interface IKeyboard
{
bool IsKeyPressed(KeyCode key);
}
...
_container.Bind<IKeyboard>().ToSingle<MyKeyboard>();
Is it possible to call the IsKeyPressed()
-method in a class without having an injected member variable?
[Inject]
private IKeyboard _keyboard
...
if(_keyboard.IsKeyPressed(KeyCode.A)
...
I.e. something like this:
if(Zenject.GetSingleton<IKeyboard>.IsKeyPressed(KeyCode.A))
...
I am making a spaceship game which currently doesn't use DI, but I have read a lot about Zenject and would like to use it. Some basic info about my game:
I was thinking about making each ship a composition root - that way I could inject ship configuration, player input etc. to the ship's submodules (which are sub transforms of the ship). The ship may be nested when docked.
This does however not seem to be entirely achievable using Zenject.
How would you use Zenject in this case?
It would be extremely helpful to have pools built into Zenject. Any type of object that needs to be created often (bullets, enemies, particles, events) would benefit greatly. My current project would fall flat on its face if I used Zenject factories as-is.
Honestly, I'm not very familiar with IoC or Zenject, so if anything here doesn't make sense, I apologize.
Pool bindings would be written like this:
// Monobehaviour to gameobject pool
_container.BindPool<Asteroid>(SceneSettings.Asteroid.Prefab, size, inflationType, overflowType);
// Short for:
_continer.Bind<IPool<Asteroid>>().To(
new GameObjectPool<Asteroid>(_container, Settings.Asteroid.Prefab, size, inflationType, overflowType));
// Concrete class to pool
_container.BindPool<Enemy>(size, inflationType, overflowType);
// Short for:
_container.Bind<IPool<Enemy>>().ToSingle<Pool<Enemy>>(size, inflationType, overflowType);
// Prefab to pool
_container.Bind<IPool<Player>>().ToSingleFromPrefab<Pool<Player>>(Settings.Player.Prefab, size, inflationType, overflowType);
.BindPool()
would be defined in DiContainer
as generic a method with one and two types along with overrides for standard and prefab pools. I'm not quite sure how you would handle the arguments for BindPool internally.
The classes Pool
and GameObjectPool
would be written custom factories similar to Factory
and GameObjectFactory
.
Example usage:
public class Enemy : IPoolable
{
public Action<Enemy> OnDeath = delegate { };
public Enemy() { }
#region IPoolable Implementation
// Reset instance to default values
public void Restore()
{
OnDeath = delegate { };
}
#endregion
private void Die()
{
OnDeath(this);
}
}
public class EnemySpawner
{
private IPool<Enemy> pool;
public EnemySpawner(IPool<Enemy> pool)
{
this.pool = pool;
}
public Enemy Create(params object[] constructorArgs)
{
var enemy = pool.Create(constructorArgs);
enemy.OnDeath += OnEnemyDeath;
return enemy;
}
private void OnEnemyDeath(Enemy enemy)
{
pool.ReturnInstance(enemy);
}
}
It looks like you guys decided to make it so 'optional' contexts will not fall back to 'parent' containers should they fail to find an appropriate binding in the base container. Is there any reason you decided to go that way?
I'm working on some experimental code using Zenject and it seems to me like it would be far more helpful if DiContainers searched fallbacks for optional bindings the same as they do for mandatory ones (simply returning null if no bindings are found therein).
I've been using Zenject version that I downloaded at 15th of August and everything is fine with it.
Today I tried to update to the latest version and it didn't work.
I reverted to my old version of Zenject and everything works fine.
Looking at the Unity profiler I am seeing that Zenject is generating garbage per frame. As I am sure you know, garbage collection performance in Unity is horrible and mid-level allocations should be avoided, especially per frame.
The biggest culprits are the two tickable handlers:
void UpdateTickable(ITickable tickable)
{
// - Allocation for use of string formatting.
// - Allocation for use of 'params' keyword (equivalent to new object[] { arg1, arg2 }).
using (ProfileBlock.Start("{0}.Tick()".With(tickable.GetType().Name())))
{
tickable.Tick();
}
}
Removing ProfileBlock
avoids some of this garbage:
void UpdateTickable(ITickable tickable)
{
tickable.Tick();
}
I propose that the above is changed to the following:
void UpdateTickable(ITickable tickable)
{
// Allow `ProfileBlock.Start` to perform formatting when enabled.
// Instead of accepting `params object[]` provide several overloads to
// accept a fixed number of parameters.
using (ProfileBlock.Start("{0}.Tick()", tickable.GetType().Name()))
{
tickable.Tick();
}
}
For testing purposes I removed the ProfileBlock from these two functions and performance was instantly better.
TaskUpdater
is another culprit of per frame allocations due to use of System.Linq
there are internal allocations plus enumerator allocations.
Changing the following:
public void UpdateRange(int minPriority, int maxPriority)
{
// Make sure that tasks with priority of int.MaxValue are updated when maxPriority is int.MaxValue
foreach (var taskInfo in _sortedTasks.Where(x =>
!x.IsRemoved && x.Priority >= minPriority && (maxPriority == int.MaxValue || x.Priority < maxPriority)))
{
Assert.That(taskInfo.Priority.HasValue);
_updateFunc(taskInfo.Task);
}
ClearRemovedTasks(_sortedTasks);
}
to the following instantly helped to improve performance:
public void UpdateRange(int minPriority, int maxPriority)
{
// Make sure that tasks with priority of int.MaxValue are updated when maxPriority is int.MaxValue
foreach (var taskInfo in _sortedTasks)
{
if (!taskInfo.IsRemoved && taskInfo.Priority >= minPriority && (maxPriority == int.MaxValue || taskInfo.Priority < maxPriority))
{
Assert.That(taskInfo.Priority.HasValue);
_updateFunc(taskInfo.Task);
}
}
ClearRemovedTasks(_sortedTasks);
}
For some reason this foreach
statement is also allocating an enumerator despite the fact that LinkedList<T>
defines a struct
enumerator.
Looking at the profiler there are several other places where Zenject is allocating per frame.
Are there any plans to support multiple constructors without having to resort to the [Inject] keyword? Ninject and StrangeIoC use strategies to resolve the best matching constructor. E.g.: Least arguments, constructor that has most injectable parameters.
This would allow me not tie to myself to the zenject assemblies in the implementation.
I see how CompositionRoot
does it's thing and it works fine in play mode, but not so much when run in Unity's integration test runner. If it is possible to make this work as it stands, it would be great to mention it into the docs.
Given that Zenject is open source and not proprietary to ModestTree it should really be in its own namespace.
Currently Zenject throws exceptions when it discovers circular dependencies. This makes sense for constructor injection, but should be possible in theory for field/property/postinject injection.
In some cases it can be tedious to, for example, add every binding to ITickable or IInitializable explicitly in the installer. What would be useful is if you could define generic conventions to always handle cases like this. We could use another fluent interface, something like the following (which is largely taken from what other DI frameworks look like)
Container.Bind(x => x.AllAssemblies.AllClasses().WhichInheritFrom<ITickable>())
.InterfaceToSingle());
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.